WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章J2ME技术进阶教程基于NOKIA的Camera MIDlet设计

基于NOKIA的Camera MIDlet设计
作者:crystal编  来源:yesky  发布时间:2005-8-27 14:59:50
简介

  本设计指南以诺基亚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类

  CameraCanvas类创建一个video player对象和一个video control,同时规定了video contro在canvas的显示方式。需要注意的是CameraCanvas对象的paint方法不能重画图像,这个方法只能重画背景和重顶端拖曳的video control,为了阐明screen已经被显示,CameraCanvas使用黄色背景,而DisplayCanvas采用青色背景。

  TakeSnapshot方法获取一个快照,并将其转化为图像数据一个PNG格式的字节数组传回到MIDlet,MIDlet再将其传回到DisplayCanvas来显示。

//unnamed package
import javax.microedition.lcdui.*;
import javax.microedition.media.*;
import javax.microedition.media.control.*;
import java.io.IOException;
class CameraCanvas
extends Canvas
implements CommandListener

{
private final CameraMIDlet midlet;
private final Commandexit Command;
private Command captureCommand=null;
private Player player=null;
private VideoControl videoControl=null;
private bool eanactive=false;
//Two strings for displaying error messages
private String message1=null;
private String message2=null;
CameraCanvas(CameraMID letmidlet)
{
this.midlet=midlet;
exitCommand=newCommand("Exit",Command.EXIT,1);
addCommand(exitCommand);
setCommandListener(this);
try{
player=Manager.createPlayer("capture://video");
player.realize();
//Grab the video control and set it to the current display.
videoControl=(VideoControl)(player.getControl("VideoControl"));
if(videoControl==null)
{
discardPlayer();
message1="Unsupported:";
message2="Can'tgetvideocontrol";
}
else{
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO,this);
//center video , letting it be clippedifit'stoobig
int canvasWidth=getWidth();
int canvasHeight=getHeight();
int displayWidth=videoControl.getDisplayWidth();
int displayHeight=videoControl.getDisplayHeight();
int x=(canvasWidth-displayWidth)/2;
inty=(canvasHeight-displayHeight)/2;
videoControl.setDisplayLocation(x,y);
captureCommand=newCommand("Capture",Command.SCREEN,1);
addCommand(captureCommand);
}
}
catch(IOExceptionioe)
{
discardPlayer();
message1="IOException:";
message2=ioe.getMessage();
}
catch(MediaExceptionme)
{
discardPlayer();

message1="MediaException:";
message2=me.getMessage();
}
catch(SecurityExceptionse)
{
discardPlayer();
message1="SecurityException";
message2=se.getMessage();
}
}
//Called in case of exception to make sure in valid players are closed
private void discardPlayer()
{
if(player!=null)
{
player.close();
player=null;
}
videoControl=null;
}
publicvoidpaint(Graphicsg)
{
g.setColor(0x00FFFF00);//yellowg.fillRect(0,0,getWidth(),getHeight());
if(message1!=null)
{
g.setColor(0x00000000);//black
g.drawString(message1,1,1,Graphics.TOP|Graphics.LEFT);
g.drawString(message2,1,1+g.getFont().getHeight(),
Graphics.TOP|Graphics.LEFT);
}
}
synchronizedvoidstart()
{
if((player!=null)&&!active)
{
try{
player.start();
videoControl.setVisible(true);
}
catch(MediaExceptionme)
{
message1="Mediaexception:";
message2=me.getMessage();
}
catch(SecurityExceptionse)
{
message1="SecurityException";
message2=se.getMessage();
}
active=true;
}
}

synchronizedvoidstop()
{
if((player!=null)&&active)
{
try{
videoControl.setVisible(false);
player.stop();
}
catch(MediaExceptionme)
{
message1="MediaException:";
message2=me.getMessage();
}
active=false;
}
}
public void commandAction(Commandc,Displayabled)
{
if(c==exitCommand)
{
midlet.cameraCanvasExit();
}
elseif(c==captureCommand)
{
takeSnapshot();
}
}
public void keyPressed(intkeyCode)
{
if(getGameAction(keyCode)==FIRE)
{
takeSnapshot();
}
}
private void takeSnapshot()
{
if(player!=null)
{
try{
byte[]pngImage=videoControl.getSnapshot(null);
midlet.cameraCanvasCaptured(pngImage);
}
catch(MediaExceptionme)
{
message1="MediaException:";
message2=me.getMessage();
}
}
}
}
DisplayCanvas类

 

[1] [2]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码