第31卷第2期 吉林大学学报(信息科学版) Journal of Jilin University(Information Science Edition) V01.31 No.2 2013年3月 Mar.2013 文章编号:1671-5896(2013)02-0152-06 Android应用中即时视频图像放大显示方法 陈 捷,何志坚,宋占伟 (吉林大学电子科学与工程学院,长春130012) 摘要:Android视频通讯应用中通常使用View类显示视频解码图像。为解决使用常用图像拉伸方式将解码到的 视频图像实时放大输出时遇到的内存严重消耗和输出延迟的问题,分析了问题的原因,并研究了基于Android 自带API(Application Programming Interface)或使用JNI(Java Native Interface)算法的即时图像放大显示方法,对 得到的图像放大效果和放大所需的时间进行实验分析,根据实验结果进行源代码分析研究,发现改进的方法, 最终提出一个解决问题的最合适的方案。 关键词:Android视频应用;图像放大;即时显示;效率分析;源代码研究 中图分类号:TP311.1 文献标识码:A Real—Time Video Image Magniifcation Method in Android Application CHEN Jie,HE Zhi-jian,SONG Zhan—wei (College of Electronic Science and Engineering,Jilin University,Changchun 130012,China) Abstract:Android visual communication applications typically use the View c]ass to display decoded video images.In order to involve the severe memory consumption and output delay problems which always encounter in the commonly used image stretching method for decoding real-time video image,we analyze the reason,and give out two other methods to achieve the real-time magniifed image display based on Android API(Application Programming Interface)or JNI(Java Native Interface).According to the experiment results,the research of source code is processed and a progressed method is achieved. Key words:Android video application;image magniifcation;real-time display;efficiency analysis;research of source code O 引 言 Android系统以其开放、免费、功能强大等多个特性已经逐渐占据了智能手机操作系统和平板电脑操 作系统的市场…,凭借其强大的API(Application Programming Intefrace)控件和高端ARM(Advanced RISC Machines)处理器的强大处理能力逐渐在可视通讯领域中发挥其巨大潜力 J。笔者目前正在研究开发基 于Android系统的视讯终端,在开发过程中需要重写Android的View控件中onDraw方法 绘制解码完成 的视频图像并放大到全屏显示,然而使用文献[4,5]或网络文档L6 中常见的创建放大图片的方式时出现 效率低、消耗大量内存的问题,不能满足较大屏幕的即时播放需求。因此,笔者在分析效率低下的原因 后,研究了Android下其他几种可行的图像放大的方法,分别进行了实验测试,得到其执行效率和放大效 果。并对各种实现方法在即时视频播放应用中的可行性进行了系统分析,最终从源代码中获得启发,得 基金项目:吉林省科技支撑计划(重点项目)基金资助项目(20100314) 储简介: ch enjiel哪一!0@mails lu edu ca 装 ,(主Te要1)从86事-13数63字05信55号22处8(理E-、m图ai1像)i. . ;宋占伟(1962一专 ),男,长春人,吉林大字教我,坝士生导帅,王妥从争甄子佰亏处埋、图像 .处理、智能交通和嵌入式系统研究,(Te1)86-431-85095828;85894687(E-mail)songzw@jlu・edu-CB。 第2期 陈捷,等 Android应用中即时视频图像放大显示方法 153 到一个兼顾放大效果和效率以及刷新可控性的最佳方案。 1 硬件与编辑器的测试平台 测试用平板电脑使用基于Cortex-A8核心,频率为1.0 GHz处理器,内存为512 MByte。Android版本 为4.0.3,Linux内核版本为3.0.8+。使用Eclipse indigo作为编程环境 7J,从视频解码器中获得的视频 图像为RGB565形式320×240像素的图像,使用Byte型数组顺序存储所有像素点的颜色信息。播放窗 口默认为480×360像素。 2 常见放大图像的方法存在的问题 文献[4,5]与网络文档 中提到对图像进行拉伸的方法,即首先创建一个原始图像的Bitmap对象, 其大小为视频解码的原始尺寸,再调用createBitmap方法结合放大矩阵Matirx创建一个放大的新Bitmap 对象。其主要实现代码如下: Matirx matrix=new Matirx(); Matirx.postScale((float)480/320,(float)360/240); NewBMP=Bitmap.createBitmap(OldBMP,0,0,320,240,matirx,true) 其中使用Matirx定义放大倍数,放大倍数是一个浮点型的小数。View及其继承类可以在子线程里调 用postInvalidate方法刷新图像,重写onDraw方法将Bitmap对象直接绘制到View的画板中即可显示放大 后的图像。该方法可以由线程主动控制刷新图像,其拉伸方式由系统决定。 使用该方法,每次处理一张解码后图片都必须创建一个新Bitmap对象,旧Bitmap图像占用的内存 变为可回收状态。由于Android不存在主动释放内存资源的方法,必须靠虚拟机自动回收资源。因为 Bitmap对象占用的内存资源量很大,一张480×360像素的图像使用565格式存放需要的内存空间为 345 600 Byte,Android下为每个应用程序分配的堆空间有限,内存损耗过大时dalvikvm虚拟机会立刻进 行内存回收 ,并产生一定的时间延迟。回收内存资源时,在开发环境Eclipse的消息窗口LogCat 9 中会 出现如表1所示的消息。 表1 Dalvikvm虚拟机自动回收内存空间的频率和图片放大所需时间 Tab.1 Frequence of dalvikvm visual machine recycling memory and the time scale of image magnification Level Time PID Apphcafion Tag Text I 11—12l9:52:咂499 1042 com. u处理时I rns 46 D 11一l2 19:2:5咂589 1012 con.gdu dalvikvm GCFORALLOC freed 338 kByte,12%free 6 638 kByte/7 495 kByte,paused 23 his —I 11-12 19:2:5 599 1042 coin.目du处理日寸1 rns 33 D l1—12 19:2:506.719 1042 coin.gdu dalvikvm GCFORALLOC freed 338 kByte,12%free 6 638 kByte/7 495 kByte,paused 30 rns I ll—l219:52:6.0749 1o42 coin. D 1l—l2 19:52: 849 oicn.gau rns 83 dalvikvm GCFORALLOC freed 338 kByte,12%free 6638 kByte/7 495 kByte,paused 20 ins —I l1—12 19:52:6.0899 1042 coin.glu处理时J Ills 92 D 11一l2 19:52:06.989 1042 coin,gdu dalvikvm GCFORAHDC freed 338 kByte,12%free 6 638 kByte/7495 kByte,pau∈ 18 rns —I l1—12 19:2:507.019 142 c0om.sOu处理时间/rns 78 D 11一】2 19:52:07.069 1042 coin.gdu dalvikvm GCFORALIDC freed 338 kByte,12%free 6638 kByte/7 495 kByte, ——17 ms 上面是一个使用这种方式解压播放9.5帧/s视频图像的测试代码执行时得到的系统消息,在这里, 放大处理时间并不包括解码所需的时间,每播放一幅画面,虚拟机就需要立刻释放338 kByte的空间,此 外还能看见释放这些数据需要的时间,为l7~30 ms不等。刷新频率越高,图片越大,导致内存的消耗 也越大,虚拟机疲于释放内存空间,处理效率严重下降 J。在测试函数两端添加了使用System. currentTimemillis方法得到的每幅图片放大所需大致时间,显示在Logcat中,后文中得到的图片处理时间 也是基于此方法。从结果中可以看出,每幅图片间隔在33~92 ms之间不等,加上释放内存需要的时间, 根据时间戳,播放一帧画面对图像的处理时间有时已经超过110 ms,这也意味着已经不能保证视频的刷 新率在9.5 s,虽然能得到图像放大的效果,但由于效率的低下,这种图像放大方式不适合在即时视 154 吉林大学学报(信息科学版) 第31卷 频刷新中使用。必须在Android的API中寻找其他放大方法。 3 Android中使用的其他放大图像方法 3.1 在本地或Java层实现软件算法放大图像 研究Bitmap类的各种创建图片方法后发现,使用Bitmap类的copyPixelFromBuffer方法可以将一个表 示像素颜色的字节数组数据写入一个现存的Bitmap中,不需要重新创建Bitmap对象。该方法支持使用 565格式的16位图片数据,也支持A8888格式的32位图片数据。因此可以编写软件算法直接处理解码 器得到的颜色数组数据进行图像放大,结果存入一个预先创建可重用且大小为放大后图像尺寸两倍的 Byte数组(假设使用l6位图片数据),再使用copyPixelFromBuffer方法将数组内容读入一个现有的Bitmap 对象,显示方式采用重写onDraw方法。使用该方式,能做到内存空间的重复利用,但算法的复杂度和处 理器性能是提高播放器刷新率的关键_1。。。 由于需要保证刷新的实时I生,考虑到设备处理器性能有限,使用软件线性插值算法 或边缘锐化增 强放大算法 都无法在有限的刷新周期(在测试平台上为110 ms)内完成所有处理。因为这些算法基本 都要对每个目标像素点进行对应位置计算 1 ,对于480 X360像素的图像,需执行172 800次变换。如果 变换过程中涉及浮点运算,则消耗的时间更多 。一个将目标图像坐标按放大比例变换为源图像坐标, 将源图像坐标对应的值作为目标图像对应坐标值的示例算法如下: int X=(int )malloc(width2 sizeof(int)); int y=(int )malloc(height2¥sizeof(int)); f0r(i=0;i<width2;i++) ( + )=(int)(i widthl/width2); for(i=0; <height2; ++) (,,+ )=(int)(i heightl/height2); for( =0 <height2 ++) ofr(i=0;i<width2;i++) { (out+i+ 木width2)=术(in+ [i]+y[ ]球width1); } 释放空间部分代码没有包含在内,其中widthl和heightl为原始图像的长宽,width2和height2为拉 伸后图像长宽。 算法中已采用了一些优化方式,由于目标图像每个横坐标像素对应的源图像横坐标位置是相同的, 纵坐标的位置同理。为减少除法运算,预先定义了两个坐标对应关系表,省略了对每个坐标都要进行的 两次除法运算,使用二重循环而不是使用一重循环的目的在于:省略一重循环中为得到目标所在的行列 位置所要进行的除法和取模运算,因为多数处理器对取模运算需要很多时间周期,如果条件允许尽量不 使用取模运算。该算法使用JNI方式编译,使用C代码能方便地将Byte数组转换为short指针取数运算。 3.2使用ImageView类的设置图片方法 考虑到项目前期完成的网络图片传输显示中使用的ImageView显示窗口,在使用setImageBitmap方 法设置显示图片且scaleType设置参数为FIT—CENTER的情况下,能自动将图片拉伸后显示,但该方法只 能用在主线程中调用,在子线程调用将抛出异常。由于View及其继承类在子线程里调用postInvalidate 方法实际上是通知主线程调用onDraw方法刷新图像,因而可通过在onDraw方法中添加setImageBitmap 过程,使主线程自动调用刷新,实现图像放大播放,其拉伸方式由系统决定。 4 放大图像测试代码执行结果分析 4.1 使用软件算法放大图像的测试代码结果 在3.1中使用的copyPixelFromBuffer能重用数据缓冲区和Bitmap对象,起到了节约内存资源的作 用,减少因为虚拟机频繁自动回收内存空间造成的延迟,最终得到的每幅放大处理时间如表2所示。 第2期 陈捷,等:Android应用中即时视频图像放大显示方法 155 同样采用在拉伸函数两端添加System.currentTimeMillis方法得到函数执行时间的方式,从LogCat中 的结果可见,这种放大方式的效率较高,每帧需要的放大时间基本上只有4 ms,能保证前面提到的 9.5 I s的帧率,在实验中有时会有一帧10~20 ms的突发情况,这与系统的其他进程调度有关_1 。该 方式不需要耗费系统频繁执行回收方法的延迟时间,已经大大减少了时间开支,以每幅视频解压需要平 均10 ms时间计算,该方式播放视频的刷新率比较容易达到6O Hz。但如果图像放大比例较大,会出现锯 齿现象,这是因为没有使用插值算法柔化边缘的缘故。如果能使用插值算法,或使用硬件对底层图像进 行处理,则图像效果会更佳。然而从算法的复杂度考虑,对于锐化和反锯齿插值算法中需要的大量浮点 运算,以及色彩565形式变换成RGB888形式进行处理的过程,测试平台使用软件方式无法在可接受的 时间间隔内达到目标,需要使用性能更高的处理器。 4.2使用ImageView类放大图像的测试代码结果 使用ImageView类放大图像的测试如表3所示。 表3使用ImageView方法放大图片的效率 Tab.3 The efficiency of scaling image with ImageView’S method 观察实验结果中的时间戳发现,使用该方式在解码开始前也在不断进行刷新,虽然该方式放大效率 很高,一般在1 ms以内,与3.1节方法一样偶尔会有10—20 ms的突发情况,但由于自动刷新的刷新率 太高,在播放帧率较低的即时采集传输视频,如前面提到韵9.5帧/S的视频时,把每1 10 ms刷新需要的 时间相加,与前一种方式每帧刷新时使用的时间非常接近,理论上有许多次处理时间是可以省略的。该 方式不能做到随子线程调用postInvalidate方法刷新这种可控刷新方法,也间接导致其他线程处理速度受 到影响。这种放大方式得到的图像经过平滑处理,图像边缘放大后比较模糊,锯齿现象不明显,然而该 方式的放大算法不可修改,不能对图像进行锐化等特殊处理,只能按系统定义的默认放大方式放大。对 于非特殊要求的应用,该放大方式比较理想,只需要研究一下如何将多余的刷新时间去除即可。 5 从源码中研究改进方式 基于ImageView类的图像放大方法单帧图像放大效率比使用软件算法的方式高,但缺乏3.1节方法 中拥有的刷新时间的可控性,存在多余的刷新时间使其效率下降的问题,由于Android的API提供了源 代码,可以从源代码中进行分析。 156 吉林大学学报(信息科学版) 第31卷 从Android SDK的Android.15源代码包资源中找到ImageView的源代码,研究源码后发现了方法2 中出现无法控制的高刷新率的原因。ImageView的setImageBitmap方法针对图像大小和视窗边界作了一 些比例运算,并根据ImageView类中名为ScaleType的设置参数调整比例矩阵mDrawMatrix,最终得到一 个源图像尺寸和显示尺寸相关的矩阵作为全局变量。setImageBitmap函数最后调用了invalidate方法使当 前画板失效,通知主线程调用onDraw方法重画,如果把setlmageBitmap写在onDraw中用于放大图像,则 相当于在onDraw方法中调用invalidate方法循环不断地使画面失效,主线程不断得到通知刷新画面重调 用onDraw方法,因此,界面刷新过于频繁,影响到其他线程的执行效率。 ImageView重写了View的onDraw方法,根据已得到的全局比例矩阵mDrawMatrix和一些设置参数在 onDraw中调用canvas的本地方法concat和translate等方式设置比例矩阵并放大图像。根据相同的原理, 3.1节中的View或SuffaceView的onDraw方法中直接加入同样一段代码canvas.concat(mMatrix),将其他 处理设置参数的过程可省略,以达到最快速最简化效果。 该本地方法的官方解释为使用当前mMatrix作为绘制图形用的放大矩阵 15]。mMatrix可以在播放窗 口建立时根据视频大小和播放窗口大小的比例预先创建,其余解码和显示图像部分和3.1节或3.2节的 方法相同,即能得到放大后的图像。值得注意的是,在每次调用onDraw方法时都需要调用该函数,否则 只对一次刷新有效。最终得到每张图片放大时间几乎都为0,且能保证每1 10 ms刷新一次。 使用该方式避免了3.2节中不断重复的刷新过程,同时也消除了该方法每次调用ImageView类的 setImageBitmap方法时放大比例矩阵的计算时间和onDraw函数中判断过程,在最大程度上提高了性能。 如果对放大后的图像清晰度效果没有特殊要求,这是测试平台上最为合适的即时视频放大手段。 6 结 语 根据实验和分析的结果表明,基于软件算法实现拉伸图像的3.1节方法刷新时间可控制,且能根据 具体需要使用边缘锐化、线性插值等特殊算法,但实现的可行性受具体算法的复杂度和硬件处理器性能 限制;基于ImageView设置图片的方法存在自动刷新率太高影响其他线程的处理性能,缺乏刷新时间可 控性的缺点,但这种方式效率较高。研究源代码发现,如果对放大清晰度效果没有要求,可以使用 canvas的一些本地方法结合缩放矩阵达到目标效果。该方式结合了3.1节的刷新可控性和3.2节效率高 的优点,目前已经在项目的视频解码应用中得到使用。笔者从研究中体会到,Android图形化界面的编程 由于资料分散,官方文档比较简略缺少范例,某些尚未被普遍使用的实用API还需要继续探索和普及。 通过阅读控件源代码发现这些新功能是一种很好的学习方法。 参考文献: [1]陈木生.GooSe Android手机推出市场分析[J].电子与电脑,2008(12):10—14. CHEN Mu—sheng.Manet Analysis When GooSe Android Phone Release[J].Compotech China,2008(12):10—14. [2]杨明极,毕晶.基于Android视频客户端的设计[J].电视技术,2012(3):43_47. YANG Ming-ji,BI Jing.Design of Video Client Based on Android[J].Video Engieering,2012(3):43_47. [3]宋强,齐贵宝,宋占伟.基于Android系统的H.264视频监控设计[J].吉林大学学报:信息科学版,2012,30(3): 272-277. SONG Qiang,Q1 Gui—bao,SONG Zhan—wei.Design of H.264 Video Monitoring Based on Android System[J].Journal of Jilin University:Info瑚ation Science Edition,2012,30(3):272-277. [4]汪永松.Android开发平台之旅[M].北京:机械工业出版社,2012. WANG Yong—song.Travel of Android Development Plaftorm[M].Beijing:China Machine Press,2012. [5]杨丰盛.Android应用开发揭秘[M].北京:机械工业出版社,2010. YANG Feng.sheng.Android Unleashed[M].Beijing:China Machine Press,2010. 『6]XPSHARP.Android图片放大缩小[EB/OL].[201 1—12-21].http://www.1inuxidc.com/Linux/201 1-12/49926.htm. XPSHARP.Enlarge or Shrink Images in Android[EB/OL].[2011—12-21].http://www.1inuxidc.com/Linux/2011-12/ 49926.htm. 第2期 陈捷,等:Android应用中即时视频图像放大显示方法 157 [7]JEROME DIMARZIO.Android:A Programmer's Guide[M].New Youk:Osborne/McGraw-Hill,2008. [8]宋小倩,周东升.基于Android平台的应用开发研究[J].软件导刊,2011(2):104.106. SONG Xiao—qian,ZHOU Dong-sheng.Development and Researh of Application Based 0n Android Platform[J].Software Guide,2011(2):104—106. [9]尹文刚,杨斌.Android应用程序中的内存泄漏与规避方法[J].单片机与嵌入式系统应用,2012(6):4-6. YIN Wen—gang,YANG Bin.Memory Leak and Avoiding Method of Android Application Prorgam[J].Mierocontrollers& Embedded Systems,2012(6):4 . [10]孙杰.基于Android平台图像处理算法的研究与实现[D].北京:北京邮电大学软件学院,2011. SUN Jie.Research and Implementation of Algorithms for Image Processing Based on Android[D].Beijing:Software Institute, Bering University fo Posts and Telecommunications,201 1. [11]江铭炎,李兴江,袁东风.2 图像插值放大处理的方法[J].山东大学学报:理学版,2003,38(3):79-81. JIANG Ming-yan,LI Xing-jiang,YUAN Dong—feng.The Method of 2 Image Enlarging with Interpolation[J].Journal of Shandong University:Natural Science,2003,38(3):79—8 1. [12]曾生达.几种图像放大算法原理比较与分析[J].金华职业技术学院学报,2012(3):66-71. ZENG Sheng—da.The Comparision and Analyisis of Several Maniifcation of Image Magniifcation[J].Journal of Jinhua Polytechnic,2012(3):66-71. [13]wu X,ZHANG X,WANG X.Low Bit—rate Image Compression via Adaptive Down—sampling and Constrained Least Squares Upconversion[J].IEEE Transactions on Image Processing,2009,8(3):552361. [14]NIU Yi,SHI Guang・ming,WANG Xiao-tian,et a1.JPEG Stream Soft—Decoding Technique Based on Autoregressive Modeling [J].The Journal ofChina Universities ofPosts and Telecommunications,2012,19(5):115-123. [15]Google Company.Android Developers[EB/OL].[2012-10].http://developer.android.corn/. (责任编辑:刘东亮)