作者:JonathanKnudsen
时间:July2003
原文出处:
http://developers.sun.com/techtopics/mobility/midp/articles/picture/源码下载:
http://developers.sun.com/techtopics/mobility/midp/articles/picture/src/Snapper.zip译者注:因为该文成文时间很早,而J2ME技术发展很快,文中提到的
开发工具和运行测试环境现在都有较大变动,请读者注意。
译文
概述
MobileMediaAPI(MMAPI)让MIDlet能够播放和录制音频和视频数据.但是设备的真实能力还是依赖于其具体实现。目前,支持MMAPI的唯一设备是Nokia3650.本文描述了如何利用MMAPI来构建一个简单的拍照程序。
开发MMAPI应用程序所用工具
构建MMAPI应用程序的第一个难题是找到正确的
开发工具.J2MEWirelessToolkit2.0 支持MIDP2.0,MMAPI1.0,WMA1.1.乍一看,它包括了你所要的一切.但是Nokia3650只能运行MIDP1.0,不能运行 MIDP2.0.为了开发MIDP1.0的应用程序,你需要J2MEWirelessToolkit的1.0.4版,外带一个支持MMAPI的模拟 器。
Sun提供这样一个模拟器,你可以在MMAPI的主页上找到(
http://java.sun.com/products/mmapi/index.jsp).尽管你可以利用该模拟器构建MMAPI应用程序,但是它不支持拍照,因此你不能用它来测试拍照的应用程序。
Nokia有一个支持拍照的模拟器,它是NokiaSeries60MIDPConceptSDKBeta0.2的一个组成部分.你可以在Nokia的开发者论坛(
http://www.forum.nokia.com)上找到.文件的名字是nS60_jme_concept_sdk_b0_2_014.zip,Linux开发者应该是用2.0版的NokiaDeveloper'sSuiteforJ2ME(
http://www.forum.nokia.com/nds_for_j2me.html),下面的安装指南只适用于windows环境。
首先,在<J2MEWirelessToolkit>\wtklib\devices目录下安装NokiaSDK(把 Nokia_Series_60_MIDP_Concept_SDK_Beta_0_2的安装目录拷贝到这个目录亦可).接下来,运行 J2MEWirelessToolkit,你就有一个额外的模拟器-- Nokia_Series_60_MIDP_Concept_SDK_Beta_0_2可用了。选择该模拟器后,你就可以构建和测试你的MMAPI应用程 序了。该模拟器和真实的Nokia3650看起来非常相似。
MMAPI的测试设备
没有什么能替代真机测试。从长远观点来看,将会有很多设备支持MMAPI,但是 Nokia3650是目前唯一支持MMAPI的设备.有好几种方式可以在Nokia3650真机上发布MIDlet.我使用红外接口在我的笔记本和手 机上传输文件。你也可以使用蓝牙和OTA.
获取照相机
MIDlet中拍照(正式的说法叫视频捕捉)的第一步是从Manager获取一个Player。一个特殊的定位符:capture://video,指示照相机使用缺省的图片大小来拍照。
mPlayer=Manager.createPlayer("capture://video");
如果设备不支持视频捕捉,这将会抛出一个MediaException。你可以预先检查一下设备是否支持拍照,如果系统属性supports.video.capture的值为真,那么该设备就支持照相功能。
为了获取拍照所需资源,Player需要被realize.如果你没有学过或者忘记了realized是什么意思,请参考<MobileMediaAPIOveriew>(
http://developers.sun.com/techtopics/mobility/apis/articles/mmapi_overview/)或者J2MEMobileMediaAPI.
mPlayer.realize();
显示相机视频
来源于照相机的视频可以作为一个Item添加到Form上,也可以作为Canvas的一部分。一个VideoControl可以让你实现这个功能,你可以采用如下语句获取VideoControl.
mVideoControl=(VideoControl)
mPlayer.getControl("VideoControl");
如果你希望在Canvas里面显示来源于相机的视频,初始化VideoControl,然后在Canvas里面设置视频的大小和位置,最后使视频可见。下 面的例子(一个Canvas字类的构造函数)显示了如何把视频摆放在离Canvas上下边框2个像素宽的位置。如果不能这样放置,构造函数试着使用整个屏 幕,最后,它调用setVisible()使视频可见.
publicCameraCanvas(SnapperMIDletmidlet,
VideoControlvideoControl){
intwidth=getWidth();
intheight=getHeight();
mSnapperMIDlet=midlet;
videoControl.initDisplayMode(
VideoControl.USE_DIRECT_VIDEO,this);
try{
videoControl.setDisplayLocation(2,2);
videoControl.setDisplaySize(width-4,height-4);
}
catch(MediaExceptionme){
try{videoControl.setDisplayFullScreen(true);}
catch(MediaExceptionme2){}
}
videoControl.setVisible(true);
}
在Form里面显示视频稍微有所不同.我们不再用USE_DIRECT_VIDEO参数调用VideoControl的initDisplayMode(),而是代之以USE_GUI_PRIMITIVE参数。在MIDP设备上,你可以获得一个Item显示在Form上
Formform=newForm("Cameraform");
Itemitem=(Item)mVideoControl.initDisplayMode(
GUIControl.USE_GUI_PRIMITIVE,null);
form.append(item);
拍照
一旦相机视频显示在设备上,拍照就很容易了.你所需要的只是调用一下VideoControl的getSnapshot ()方法。为了调用该方法,你需要传递一个图片类型参数,如果你使用null作参数,那么相机就会适用缺省的图片类型?PNG.通过获取用空格隔开的系统 属性video.snapshot.encodings的值,你可以预先获取相机支持的图片类型。
ThegetSnapshot ()方法返回一个字节数组,里面是按你所指定的图片格式的图片数据。接下来,你就可以随意行事了,你可以把这个字节数组存储在数据库里,也可以把它发到服 务器上去,或者依据这个字节数组构造一个Image对象,这样你就可以把刚才所拍照片显示在用户面前,如下例所示:
byte[]raw=mVideoControl.getSnapshot(null);
Imageimage=Image.createImage(raw,0,raw.length);
创建微缩图
在这篇文章中,我想要谈谈如何创建微缩图片,也就是使所拍的相片缩小化。这事看起来简单,其实却并不轻松。 MIDP2.0中包含一些方法,这些方法可以从Image对象中获取原始的像素数据,有可能实现图像的伸缩变换。不幸的是,MIDP1.0并不提供对像素 数据的直接访问。
从图像处理角度来看,我这里采用的解决办法既不优雅,也不严格正确。但是这种办法接近我所需要的效果,并且不涉及到手工解析 PNG格式。我创建了一个新的空白的图片作为微缩图,对于图片的每个像素,我设置一个围绕该像素的极小的剪切区。然后把原始图片绘制在一个适当的位置上, 这样就设置了微缩图的每一个像素.
privateImagecreateThumbnail(Imageimage){
intsourceWidth=image.getWidth();
intsourceHeight=image.getHeight();
intthumbWidth=64;
intthumbHeight=-1;
if(thumbHeight==-1)
thumbHeight=thumbWidth*sourceHeight/sourceWidth;
Imagethumb=Image.createImage(thumbWidth,thumbHeight);
Graphicsg=thumb.getGraphics();
for(inty=0;y<thumbHeight;y++){
for(intx=0;x<thumbWidth;x++){
g.setClip(x,y,1,1);
intdx=x*sourceWidth/thumbWidth;
intdy=y*sourceHeight/thumbHeight;
g.drawImage(image,x-dx,y-dy,
Graphics.LEFT|Graphics.TOP);
}
}
ImageimmutableThumb=Image.createImage(thumb);
returnimmutableThumb;
}
Snapper例子
从本文下载的源代码是一个叫做Snapper的程序。Snapper让你可以把所拍照片的所有微缩图都显示 在一个Form里.本文所引用的代码来源于Snapper.Snapper程序仅包含2个类。SnapperMIDlet提供应用逻辑和视图流程控制,与 绝大部分的MMAPI代码相似,需要创建Player,获取snapshot.CameraCanvas是一个Canvas的子类,它包含一个 VideoControl来显示相机视频。
Snapper能聪明的发现目标设备是否支持视频捕捉,如果你在Sun的MME模拟器上运行该程序,你会收到一个优雅的反馈信息:
在不支持视频捕捉的设备上运行Snapper
如果你使用Nokia的Concept模拟器,你将看到如下效果:
Snapper的主屏
选择Camera命令(Nokia机型把该命令放在Options菜单里),在一台真机上,你可以看到来源于摄像头的视频,模拟器只能显示单幅的静态图像。但是在这2种情况下,CameraCanvas都会在视频周围画上一个绿框。
Snapper的摄像机屏幕
要拍照的话,你只需选择Capture命令或者按开火键(位于方向键中心),Snapper将创建一个微缩图片并显示在MIDlet的主屏上。
放置了微缩图的Snapper主屏
未来的改进
Snapper是一个非常简单的例子,但是有很多有趣的地方你可以改进。
1.你可以把整个相片保存在数据库里,这样你可以在今后浏览。
2.你可以允许玩家删除相片,或者改变其次序
3.你可以把整个相片发送到一个服务器上存储起来,并且提供一个Web视图进行浏览。
4.使用MIDP2.0,你可以对图片做标准的变换处理:模糊,锐化,颜色反转,几何变换等等。
总结
MMAPI是一个灵活而强大的API,它让开发者能表现和捕获音频和视频数据。本文描述了MMAPI的拍照功能,所需工具, 以及如何编写拍照的MIDlet.Snapper例子实现了拍照功能和微缩图功能。你只要稍作加工,该例子就可以成为一个网络相片共享程序的基础.
关于作者
JonathanKnudsen出了好几本书,包括《WirelessJava (secondedition)》,《TheUnofficialGuidetoLEGOMINDSTORMSRobots》, 《LearningJava(secondedition)》,《Java2DGraphics》。Jonathan在Java和 Legorobots方面广泛写作,他还为JavaWorld,EXE,NZZFolio, andtheO'ReillyNetwork写文章.Jonathan在普林斯顿大学获得了机械工程学位.
关于译者
陈万飞,网名Jagie,培训师,爱好java技术.可通过
chen_cwf@163.com与他联系
分享到:
相关推荐
- 示例代码库:通过实践加深理解,逐步掌握MMAPI的使用。 通过深入学习和实践,开发者将能够充分利用MMAPI的强大功能,开发出适应各种移动设备的创新多媒体应用程序。JSR-135课程将引导你逐步掌握这一领域,成为...
- 引入包:在使用MMAPI时,需要在代码中引入`javax.microedition.media`包。 - 创建Player:通过Manager的`createPlayer()`方法创建Player对象。有三种创建方式: - 通过媒体的URL创建:`createPlayer(String ...
MCI能够直接控制硬件设备,如CD音乐和影碟机,也可以通过底层的MMAPI间接控制MIDI、WAV等设备,甚至提供如AVI/MPEG影片播放器这样的DLL高层接口。 MCI设备主要有两种类型: 1. 简单设备:这类设备无需提供数据文件...
通过学习这份文档,开发者不仅可以了解如何使用这些接口创建多媒体应用,还能掌握如何处理设备兼容性问题,因为Mobile Media API设计时就考虑到了不同设备的差异性。同时,文档中的示例代码也能帮助开发者快速上手...
这个例子展示了如何使用 MMAPI 加载并播放一个 MP3 文件,并设置音量和播放循环次数。 总的来说,J2ME 的 MMAPI 是开发移动设备多媒体应用的重要工具,它使开发者能够创建功能丰富的应用程序,提供丰富的用户体验。...
在J2ME应用开发中,利用MMAPI(Mobile Media API)可以实现在手机上开发与摄像头交互的程序,使得用户可以在游戏中或者其他应用程序中捕获和处理摄像头的图像。以下是对MMAPI开发手机摄像头程序的详细说明: 首先,...
### J2ME中使用MMAPI开发手机摄像头程序详解 #### 概述 J2ME(Java 2 Platform Micro Edition)是Sun Microsystems为嵌入式和移动设备设计的Java平台。MMAPI(Multimedia API)是J2ME平台的一个扩展,提供了多媒体...
Pro Java ME MMAPI Mobile Media API for Java Micro Edition
- 编程工具:主要使用API(如MCI、DirectX)、编程语言(如Visual C++、Java)和接口(如MDK、SDK、DLL)进行低层或高层编程。 - 著作工具:包括基于图标、时间、页和网页的著作系统,如Authorware、Director、...
在本篇文档中,我们介绍了如何在BlackBerry平台上使用MMAPI进行拍照应用的开发,包括获取支持的照片规格、定义照片规格类以及如何获取和解析这些规格。这些基础组件为后续的拍照应用开发打下了坚实的基础。开发者...
`mmapi` 使用 Python 语言进行开发,这得益于 Python 的强大功能和易用性。Python 在 Web 开发领域广泛应用于构建 RESTful API,因为其拥有丰富的库和框架,如 Flask、Django 和 FastAPI,它们简化了HTTP请求处理、...
在J2ME应用开发中,实现手机拍照功能主要依赖于MMAPI(Mobile Media API)扩展包中的VideoControl和Player接口。以下是对实现这一功能的详细解析: 首先,要创建一个Player对象,它是处理多媒体数据的核心组件。...
BlackBerry SDK 5.0 以及之前的版本通过MMAPI 实现拍照功能,主要的功能包包括: javax.microedition.media javax.microedition.media.control javax.microedition.amms.control.camera 拍照应用包括如下几...
在J2ME中,移动媒体API(Mobile Media API,MMAPI)是用于在这些设备上处理多媒体内容的核心接口,提供了播放、录制音频和视频的功能。本开发者指导将深入探讨MMAPI的各个方面,帮助开发者充分利用这个强大的工具。 ...
总的来说,J2ME的MMAPI为移动设备提供了丰富的多媒体功能,但它的使用需要考虑到设备的多样性。开发者需要学习如何利用Player、Control和Manager来实现跨设备的兼容性,同时通过DataSource灵活地处理不同类型的媒体...
`ClientBox`类包含了设备搜索、服务搜索以及使用MMAPI(Mobile Media API)进行语音处理的功能。 - 设备搜索:通过`LocalDevice`获取本地蓝牙设备,并使用`DiscoveryAgent`进行远程设备的发现。`DiscoveryListener`...
使用绿色按钮将文件下载为zip格式,或使用Git将存储库克隆到您的计算机上。 发行版 版本v1.0对应于已出版书籍中的代码,没有更正或更新。 会费 请参阅文件Contributing.md,以获取有关如何为该存储库做出贡献的更多...
“第13章__MCI和MMAPI编程C.doc”可能会深入讲解如何同时使用MCI和MMAPI(Microsoft Multimedia API)进行更复杂的音频处理。MMAPI提供了一种低级别的访问方式,可以进行更为细致的音频控制,比如混音、采样率转换等...