截图 不需要专用工具

技术与开发

手机上有专用截图工具,但需要单独调用,如果开发的程序嵌入了截图模块,在程序使用时按一个键就直接截图了,会让程序更加人性化。

截图模块设计思路

截图模块的作用是将当前屏幕中的内容存储起来,而被存储起来的内容可以发送给好友或存储到本地(截图模块下载地址:http://www.shudoo.com/bzsoft)。截图模块的用途比较多,例如嵌入手机游戏中,在手机游戏中通关时可以直接截图;嵌入浏览器中,上网时看到有趣的新闻可以直接截图等。

设计截图模块(图1),先要设计一个截图界面,然后设计一个计数进程,这个进程的作用是每隔0.1秒计数一次。再设计一个截图的快捷键,例如“#”号键。当用户按下手机上的“#”号键时,保存屏幕内容,再将存储的内容转换为图片。当截图效果图显示达到3秒时(时间可以修改),自动切换到正常的界面。截图会保存到记录目录。

20-f11-1-1.jpg

用缓冲方式截图

截图模块的关键就是屏幕存储,有两种实现方法。

方法1:依次读取屏幕上每个点的信息并进行保存。这种方式是利用系统提供的读取屏幕的函数获得信息。

小知识:常见的PC屏幕一般是1024*768,表示屏幕被分为1024列、768行,则屏幕上点的总数量为:1024X768=786432个。Nokia S60系列的手机是176*208,表示屏幕被分为176列、208行。

方法2:借鉴“双缓冲”技术的思路,将需要绘制的内容全部绘制在一张缓冲图片中,然后将缓冲图片的内容转换成某种格式存储起来。

小知识:双缓冲(double buffer)是一种解决在播放动画时屏幕闪烁的技术,该技术在程序中的使用范围很广泛,是一种很成熟的实用技术。

在PC编程中,由于第一种方法实现起来比较简单,所以多采用第一种方式。而J2ME技术是不支持第一种方法的,所以我们采用第二种方法实现屏幕存储。如果要使用第一种方法,可以换其他的语言。

在程序中将界面的内容全部绘制在一张预先创建完成的“缓冲图片”中,该缓冲图片上绘制的内容就是手机屏幕显示的内容,程序界面中的变化也就是缓冲图片内容的变化,在需要存储时,调用图片Image对象中的getRGB获得每个点的颜色信息,然后将所有的颜色信息存储起来,例如:

private void saveImage(){

imgWidth = width;

imgHeight = height;

rgb = new int[imgWidth * imgHeight]; //屏幕大小

//将图片信息读入数组中

bufferImg.getRGB(rgb, 0, imgWidth, 0, 0, imgWidth, imgHeight);

save(); //保存到记录仓库

“双缓冲”技术除了可以用来设计截图模块,还可以用来设计预览模块以及在绘制块状地图时提高程序的执行效率等。

截图模块设计步骤

第一步:创建项目

启动Eclipse环境,选择“File→New→J2ME MIDlet Suit”,设置项目名称为“ScreenSave”,并一路选择“Next”, 完成项目的建立。然后新建一个J2ME入口类,选择“File→New→J2ME MIDlet”,并设置名称为“ScreenSaveMIDlet”,点击“Finish”。创建项目的代码下载地址是http://www.shudoo.com/bzsoft。

第二步:设计界面

选择“File→New→Class”,并设置名称为“MainCanvas”,点击“Finish”完成界面类的创建。接着,开始初始化界面。关键码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

//绘制数字

bufferG.drawString(String.valueOf(n), width/2,

height/2, HCENTERBASELINE);

//绘制按钮文字

bufferG.drawString(screenSaveInfoStr, width/2, height, HCENTERBOTTOM);

bufferG.drawString(quitStr, width, height, RIGHTBOTTOM);

//绘制缓冲图片

g.drawImage(bufferImg, 0, 0, TOPLEFT);

第三步:设置#号键

在程序运行时,按下手机上的#号键,启动截图功能并将截图的效果显示3秒,然后程序继续运行。核心代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

public void keyPressed(int keyCode){

switch(status){

case NORMAL:

if(keyCode == Canvas.KEY_POUND){ //#号键

saveImage(); //保存图片

savedImg = displayImg(); //获得保存的图片

status = DISPLAY_SAVED;

}

if(keyCode == -7){

ScreenSaveMIDlet.quitApp();

isRun = true;

第四步:3秒计时

当截图功能启动后,在线程中每隔0.1秒计数一次,达到3秒后界面切换回正常的界面。

核心代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

public void run() {

try{

while(isRun){

Thread.sleep(SPF); //延时SPF

logic();

}

}catch(Exception e){}

private void logic(){

switch(status){ //根据状态值进行不同的处理

case NORMAL: //正常状态

n++; //数字值增加1

repaint(); //重画界面

break;

case DISPLAY_SAVED: //显示截图状态

count++; //计数

if(count * SPF >= 3000){ //显示时间达到3秒

status = NORMAL; //切换到正常状态

第五步:运行程序

在Eclipse主界面左侧的“Package Explorer”中,选中项目源代码“ScreenSaveMIDlet.java”,单击鼠标右键,选择“Run As→Emulated J2ME Midlet”即可运行程序(图2)。

20-f11-1-2.jpg

读者反馈

开发QQ群:看了上期的文章,我想把户外模式再细化一下,分成清晨户外、中午户外、下午户外,不知道《电脑报》小编有什么建议?

小编:你这个提议很好,在程序中可以实现。在实际设计时,需要根据各种户外模式的光照强度等,重新设置合适的文字颜色、背景颜色和屏幕亮度。

开发QQ群:看了上期的文章,夜间模式是程序设定好了的,可以让用户自己设定不?

小编:在该示例程序中,夜间模式及其他模式,都是由程序预先设置好了相关的数值,其实要让程序更加人性化,应该允许用户自己进行设定,或者将固定模式和用户自定义模式组合使用。在技术上,让用户自己设定模式是可以实现的,需要增加自定义模式的模块。

开发QQ群:为什么我下载的Nokia S40模拟器不支持中文显示?

小编:在Nokia的官方网站上,可以下载Nokia S40系列的专用模拟器,其下载地址为:

http://www.forum.nokia.com/info/sw.no

kia.com/id/cc48f9a1-f5cf-447b-bdba-c4d

41b3d05ce/Series_40_Platform_SDKs.html。但是如果只安装该SDK的话,是无法显示中文的,需要再专门下载语言包,选择模拟器“Tool-Preferences”中的“Download languages”下载并安装语言包,然后重新启动模拟器,在相同的位置设置“Current language:”为“Chinese_simplified”即可。

开发QQ群:是否可以实现用程序控制手机的摄像头?

小编:如果手机支持的话,可以设计控制手机的摄像头程序,从而实现拍照和录制视频的功能。手机要支持MIDP2.0或MMAPI可选包(MIDP2.0中包含的支持视频编程的框架是MMAPI的一个子集),这样才能进行编程。

读者问题:“弱弱”地问一下,如何在手机程序中添加读取手机电话簿的功能?希望高手给我指点迷津。

高手 二龙宝:在标准的MIDP API中,是不支持读取手机电话簿的,如果要读取,则需要手机支持JSR75中的PIM API。如果手机支持JSR75可选包,即可调用该组API读取电话簿。但是在读取时,手机上会弹出相应的提示窗口。

读者问题:我要在手机程序中设计一个定时器,定时器会调用函数访问一个类的成员,我应该怎么设计?

你是手机编程的高手吗?你能解答上面这位读者的疑问吗?不要犹豫,来我们这里展示一下你的风采吧,来信请发到pcw-chendx@vip.sina.com(也可以给我们发送问题)。

第四个QQ群: 9822280,验证码:手机开发,欢迎对手机编程感兴趣的朋友加入。