简介
本设计指南以诺基亚3650为设计原型。一些基于MIDP的移动电话使用移动多媒体API,这些API使MIDlets具有更强大的多媒体能力,尤其是可以支持通过移动电话的照相设备进行图像捕获。
这个指南描述了照相MIDlet,提供了一个简单的使用这种图像捕获能力的示例程序。这种照相MIDlet非常简单特别适合作为使用指南介绍。所以在本指南中提出了一些扩展的方法。
本文假设你假设你已经了解Java编程,同时也了解了基于MIDP的编程,如果您没有这些基础,那么请先学习MIDP编程。
移动多媒体API进行图像捕获
移动多媒体规范包括了怎样使用照相设备捕获图像的代码片断,照相MIDlet使用了同样的技术。
首先必须创建一个用户:
| Playerplayer; … player=Manager.createPlayer("capture://video"); |
然后初始化用户:
| player.realize(); |
下面我们需要一个显示图像的video control:
| VideoControlvideoControl; … videoControl=(VideoControl)player.getControl("VideoControl"); |
video control有两种显示模式:一种是作为MIDP低层用户接口Canvas对象出现;另一种是作为MIDP高层用户接口窗体控件出现。在这类MIDlet中可以使用Canvas方式,但在第5部分选择执行中需要选择窗体模式。
| videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO,canvas); |
启动原先创立的Player对象,以便用户可以看见照相头的指示:
| player.start(); |
一旦照相启动,就可以获得一个简单的图像的数据:
| byte[]pngData=videoControl.getSnapshot(null); |
getSnapshot方法的参数代表获得图像数据的格式,如果该参数为NULL,那么表明获得图像的格式为PNG,这样就保证图像能被所有设备执行。
获得的数据可以由多种方式使用,比如该数据可以存储起来稍后使用,也可以用HTTP方式发送到服务器,也可以立即将其作为一幅图像显示出来,要立即显示可以使用Image对象的createImage(byte[], int, int)方法:
| ImagephotoImg=Image.createImage(pngData,0,pngData.length); |
图像和图像数据将占有大量内存,所以在不再需要以后要将其释放。
照相MIDlet设计
用户界面设计
照相MIDlet有两种屏幕可供选择:

图1
第一种屏幕是显示镜头前连续的视屏图像,当用户认为镜头图像已经选择好了只需要简单的选择"Capture"或"game action"按钮。

图2
第二种是显示获得的静态照片,为了使文中的MIDlet实例更为简单,所以我没有对图像作任何其他操作,包括存储或发送其他地方。
软件设计

图3 Camera MIDlet类框图
从框图中我们可以清楚的看到CameraMIDlet创建了CameraCanvas 和 DisplayCanvas,CameraCanvas需要一个由MMAPI Manager类创建的图像捕获player并接受一个执行player接口的对象,这个对象需要Video Control并接受一个执行VideoControl接口的对象。你不需要了解更具体的情况,只需通过界面与这些对象的交互就可以了。
示例程序
CameraMIDlet类
MIDlet类控制显示的screen用户界面,当screen需要转变到其他的screen时,screen将回调其自身,screen不能直接与其他screen接触。
| //unnamed package import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class CameraMIDletextendsMIDlet{ private CameraCanvascameraCanvas=null; private DisplayCanvasdisplayCanvas=null; public CameraMIDlet() { } public void startApp() { Displayablecurrent=Display.getDisplay(this).getCurrent(); if(current==null) { //firstcallcameraCanvas=newCameraCanvas(this); displayCanvas=newDisplayCanvas(this); Display.getDisplay(this).setCurrent(cameraCanvas); cameraCanvas.start(); } else{ //returningfrompauseAppif(current==cameraCanvas) { cameraCanvas.start(); } Display.getDisplay(this).setCurrent(current); } } public void pauseApp() { if (Display.getDisplay(this).getCurrent()==cameraCanvas) { cameraCanvas.stop(); } } public void destroyApp(booleanunconditional) { if(Display.getDisplay(this).getCurrent()==cameraCanvas) { cameraCanvas.stop(); } } private void exitRequested() { destroyApp(false); notifyDestroyed(); } void cameraCanvasExit() { exitRequested(); } void cameraCanvasCaptured(byte[]pngData) { cameraCanvas.stop(); displayCanvas.setImage(pngData); Display.getDisplay(this).setCurrent(displayCanvas); } void displayCanvasBack() { Display.getDisplay(this).setCurrent(cameraCanvas); cameraCanvas.start(); } } |
CameraCanvas类






