论文第1章:绪论

面向移动设备的矢量绘图平台设计与实现

Design and Implementation of Mobile Device-oriented Vector Drawing Platform

引用本论文: 张云贵. 面向移动设备的矢量绘图平台设计与实现[D]. 北京:北京理工大学软件学院, 2013.

本论文的相似度为0%,是源创论文。欢迎评阅,请勿抄袭。

如果在研究或论文中使用到,欢迎回复或私信你的学校、姓名、研究领域,并在论文中添加引用或致谢。感谢你对开放成果的尊重和鼓励。

第1章 绪论

1.1 研究背景和意义

传统的移动设备不适合交互式绘图应用[1]。2010年iPad发布后,涌现了各种平板电脑,目前,国内的平板电脑以Android和iOS操作系统为主。其高分辨率、较高配置、便携性和性价比使其适合于较复杂的交互式矢量图形应用。

在iOS和Android上,国内的二维交互式矢量绘图软件极少,缺乏通用绘图的开源框架。移动设备的硬件架构、交互方式及开发环境与PC机相差很大,开发难度高。2012年国内数字化教育发展迅速,移动终端的应用成为重点[2]。面向移动设备的矢量绘图技术在移动学习和互动教学应用(例如手写批注、图文笔记、几何教学、汉字书写)中具有较大的发展空间和应用价值。

根据以上现状的分析,确定选题为研究面向移动设备(iOS和Android操作系统)的交互式二维矢量绘图平台。因为不同应用领域的需求差异大、多数开发人员能够胜任软件界面定制和业务功能扩展的开发,所以将研究范围限定在二次开发平台(通用开发包)及底层实现上。以跨平台开源框架的形式避免在不同平台上重复开发、扩大适用范围。该平台将应用于互动课堂教学、阅读批注和图文笔记等多种软件中。

1.2 国内外研究现状

1.2.1 移动图形引擎的研究现状

在移动设备上的二维图形引擎主要分为下面三大研究方向。

(1)基于渲染流水线的OpenGL ES[3]和OpenVG[4][5]。前者适合于三维浏览和游戏应用,跨平台性和硬件加速是其主要优点,国内研究很多,有较多开源框架。但使用其进行二维绘图开发会加大系统复杂性、增加开发成本。而OpenVG适合于SVG和Flash等二维图形的高质量渲染场合,目前应用在GIS和导航等少数领域。

(2)基于画布模型的二维图形库[6][7]。相对于渲染流水线方式其开发难度较低、与操作系统的内置界面库融合程度高。iOS和Android的核心图形库分别是Quartz 2D和Skia(其Java封装框架为Android Canvas)。Quartz 2D内部可以使用OpenGL ES进行图形渲染和层合并。Android从3.0起可以使用OpenGL ES对多数绘图API进行硬件加速。因此基于画布模型的图形库在移动设备上也具有较高的性能。

(3)基于HTML5 Canvas或移动SVG的实现方式[8]。通过JavaScript脚本实现交互绘图,其跨平台性、丰富渲染特性和开发难度较低是其主要优点。由于运行开销较大和网页浏览器兼容问题等原因,目前在移动设备上应用还不多。

1.2.2 矢量绘图相关的开源项目

表1‑1 移动平台上的二维绘图开源框架

开源项目

编程语言

特点

PocketSVG

ObjC

从SVG文件生成CAShapeLayers或路径对象

SVGKit

ObjC

显示和交互操作SVG图形,使用CoreAnimation显示

iPhoneTextReader

ObjC、C

使用Quartz 2D显示多种格式的电子书

Core-Plot

ObjC

使用Quartz 2D和Core Animation 显示图表,可显示动态变化的图形和光滑曲线

ECGraph

ObjC

使用Quartz 2D显示静态图表

SmoothLineView

OjbC

使用Quartz 2D快速绘制光滑曲线

Vectoroid

Java

基于ImageView交互式绘制图形,可读写SVG文件

AndroidPlot

Java

基于View或Widget显示静态和动态图表

svg-android

Java

基于PictureDrawable 显示SVG文件的图形

TPSVG

Java

基于Drawable 显示SVG文件的图形

AChartEngine

Java

显示多种图表,有扩展框架ChartDroid

DroidGraph

Java

显示图表,饼图和线图

DroidCharts

AFreeChart

Java

显示多种图表,JFreecharts的Android移植版,在应用程序中将Canvas传给该框架实现绘图

jjoe64/GraphView

Java

显示条状图和线图,可滚动和放缩显示

在iOS和Android上,国外的二维交互式矢量绘图软件较多[9],国内极少。开源软件或框架较少,表1‑1列出主要的二维矢量绘图开源框架(OpenGL ES通常用在游戏引擎和复杂的图形平台中,本文不作研究),这些框架大多在2011-2012年发布。

iOS绘图框架通常基于Quartz 2D图形库开发,基于CoreAnimation动画引擎实现高性能的动态绘图,基于图像视图或CAShapeLayers显示大量图形。Android绘图框架则主要基于普通视图交互绘制。基于图像视图或可绘制对象的渲染方式用于图形较多的场合。这些开源绘图框架使用C/C++实现的很少,难以同时适用于iOS和Android。

1.2.3 iOS绘图优化技术

杨硕飞在2011年使用Quartz 2D取得了较好的绘图效果[10]。除此之外国内对该图形库的学术研究较少,在互联网上的官方资料和翻译文章较多,应用较广泛。

双缓冲显示技术在PC上很常见,但照搬到iOS上容易出现问题:在iPad 3等显示屏设备上绘图很慢(创建位图没有考虑屏幕放大比例时会更慢)。其主要原因[11]是在缓冲位图上绘图无法使用GPU的加速特性,复制图像和插补运算很耗时。

离屏渲染技术是移动设备上常用的加速绘图技术,其原理是先渲染图形或图像到CALayer(内部有矩形纹理)中,在界面显示时由GPU合成到屏幕帧缓存中。图形绘制阶段是在CPU上进行的,图形复杂时难以快速显示。为了更快显示复杂内容,可采用渐进式渲染技术[12]。在用户交互变慢或CPU空闲时在后台线程中进行填充等更丰富的渲染操作。对于拖动平移或捏合放缩动作,即时显示所有图形影响体验,可只改变CALayer的变换矩阵[13],由CoreAnimation快速显示。

离屏渲染技术又称为预渲染技术,Kurt总结了两种实现方法[14]

(1)将绘制好的位图放到UIImageView中,让该视图以矩形纹理方式交给GPU合成显示,避免了在CPU上进行位图复制操作(位图的显示涉及内存复制操作)。

(2)将离屏缓冲位图作为视图的层(CALayer)的内容,但不能实现drawRect函数、不能调用setNeedsDisplay函数,并确保视图的内容模式不为重绘模式。

对于第一种方法,可以使用透明视图进行触摸响应和动态图形显示,在其下层采用图像视图,在触摸结束后在后台线程中合并图形到图像视图。由于避免了位图复制操作,该方法能达到60FPS的流畅程度[15]

在使用离屏渲染技术可能遇到这两个问题[16]。(1)由于Quartz 2D使用CPU进行绘制,如果绘制时间太长就会出现wait_fences错误。(2)Quartz 2D在屏幕显示时直接在矩形纹理上绘制,这可避免大内存复制,如果超出GPU的缓冲大小(超过屏幕大小或层太多),就会在普通内存块上绘图,然后提交到GPU,这会导致性能问题。解决方法:(1)减少绘制内容。例如,不显示不可见的图形、在动态放缩时仅显示图形外边框。(2)将复杂内容分成多个视图或子层渲染,不必全部重新渲染。

将CALayer标记为光栅化层能够减少复杂图形的渲染频度,但如果视图经常改变内容就会降低性能,需要禁用自动光栅化,不使用额外的缓冲位图。

对于大图片,避免通过剪裁显示和使用drawRect显示,可使用多个CATiledLayer分区拼接显示。其他优化方法有:(1)将多条线段合并到一个路径中批量绘制;(2)动画显示时不使用反走样、不显示文本内容;因为Quartz 2D需要使用单独缓冲渲染这两种内容,(3)使用整数像素坐标能避免自动反走样。

1.2.4 Android绘图技术

Android绘图的主要实现方式是基于SurfaceView的多线程绘制方式、在本地动态库中使用Skia的实现方式,而基于普通View的绘制方式性能相对较低,基于图像视图或可绘制对象的渲染方式用于图形较多的静态图形的绘制中。

高帧率绘图主要使用OpenGL ES或SurfaceView实现,后者容易使用。Chris介绍了后者的经典实现方式[17]:在主线程处理触摸交互事件,在内容线程计算和管理图形,由SurfaceHolder控制的渲染线程只进行每帧的绘制。Chris建议避免内存申请和释放,以避免垃圾回收的暂停影响。Chris通过性能对比指出Canvas对于图形不是太多、更新频度不高的场合,其性能也不差。

从Android 3.0起在屏幕绘图时可使用OpenGL ES 2.0硬件加速绘图,Android 4.0默认全面硬件加速。基于位图的Canvas仍然使用软件渲染方式。Ryan指出该硬件加速特性的缺点是个别显示效果会改变、多占用进程的2~8MB内存,简单使用硬件加速绘制所有图形会导致在部分机型上性能变差[18]。视图的层使用硬件加速时,会占用较多内存,官方推荐仅在动画显示时使用硬件加速。

Robert建议对程序背景图使用RGB_565编码(通常是ARGB_8888),减少透明视图的层次,减少浮点运算量[19]。这样能大幅减少CPU的渲染时间。Android官方针对性能和JNI设计提出了很多建议。例如,使用静态方法而不是虚方法。

1.2.5 图形引擎跨平台的方式

在使用基于画布模型的图形库方面,很多软件都基于某一种图形库(例如Quartz 2D、GDI+)实现,如果要移植到不同的操作系统上就会很困难。对此侯炯总结了WebKit基于图形库适配器的跨平台策略[20]:定义统一的画布接口,在外部插件中使用某种图形库实现该接口。这样确保内核模块跨平台、对应用提供相同的接口。

图形中间件[21]是更进一步的跨平台方式。除了屏蔽图形库差异性外,还可根据应用对性能和内存资源的需求选择基于预缓存的渲染驱动方式和基于图形库适配的渲染驱动方式。还有一种方式是采用跨平台的渲染算法实现图形引擎[22]

为了弥补某些图形库缺少特定类型曲线的问题,通常将曲线转换为三次贝塞尔曲线[23]。例如使用三次贝塞尔曲线表示任意角度的圆弧、四段Bezier曲线表示椭圆、将B样条曲线和三次参数样条曲线分解为连续的三次贝塞尔曲线。Mike总结了基于三次贝塞尔曲线[24]的计算技术。例如曲线转换、包络框、点中测试、图形相交、分割和拼接、外扩、裁剪。

1.2.6 多点触摸和手势识别

Luke总结了十种经典的核心手势,单指手势有单击、双击、拖动、快滑、长按,双指手势有缩放、旋转、长按并单击、长按并拖动[25]。最后两种手势在主流操作系统中没有内置支持[26],单指手势都支持,在Android上需要自行识别旋转和缩放手势。研究表明食指、中指或五个手指在交互中使用得最多[27]。较多Android机型最多同时识别三个触点信号[28]。所以在绘图平台中应尽可能只使用单指和双指手势。

将触摸事件识别为手势的一个常见问题是手势二义性(手指动作可理解为多种相似的手势类型)。一般通过延迟发送技术解决[29]。基于触点的触摸状态、位移和时间的方法可解决几种手势的冲突[30]:(1)快滑和拖动通过滑行的距离判断;(2)单击、长按和双击手势通过两次点击的时间间隔和按下持续时间判断。在iOS上除了采用延迟开始和延时结束的方法外,还允许应用程序使用这几种方法:设置手势静态依赖关系、动态判断新触点能否加入到某个手势、允许对多个手势进行同时识别判断。

1.2.7 编程语言和开发方式

C++适合大多数移动平台。如何在多种平台上实现统一的绘图接口是将要面临的一个难题。iOS程序可以在一个文件中同时使用ObjC和C++,通过C++类重载的方式实现扩展和集成。在Android平台上主要使用Java及Android SDK开发应用程序,使用C/C++及Android NDK开发JNI接口的本地动态库[31]

Android本地动态库的开发存在较多困难,主要有JNI编写、NDK编译和调试、内存泄漏和溢出问题。SWIG可以将C++连接到JNI接口。Charles在2010年发现使用SWIG生成的Java类不适合Android的Dalvik虚拟机[32],改用javah工具从Java类生成JNI导出函数,只能生成C语言的函数定义文件。目前,这些程序的Java代码很少调用C++的类接口,一般是将C++代码封装到C函数中。Android代码从C++类继承和扩展则几乎没有。Android官方也建议少用虚函数、慎用JNI本地接口。因此需要研究Java与C++衔接的有效方式,降低开发难度。

本文研究发现SWIG官方在2012年4月修复了该问题,Onur Cinar在同年12月出版的专著中介绍了SWIG与NDK结合的实现方法[33]。因此可以使用SWIG新版本开发Android本地动态库。

1.2.8 Android内存访问

在针对Android设计绘图接口时应尽可能使用简单数据类型,少用包装对象,以避免JNI接口的性能损失。由于Dalvik最多支持512个JNI本地引用对象,容易出现内存溢出的问题,在JNI内部实现上要注意释放JNI引用对象[34]

Android的每个进程默认最多使用16MB内存,容易出现内存溢出问题[35]。通常的解决方法是使用软引用缓存位图对象[36]。但Android 2.3以后软引用对象会被强行回收(弱引用对象回收更快),而且从3.0起位图数据改放到本地库内部,无法预知其释放时机,容易引起内存溢出问题。可使用LruCache或DiskCache进行缓存。其他方法有:(1)在显示小图片时降低采样率以便减少内存占用量。(2)对Activity(应用程序组件)内的线程和异步消息响应者(Handler)特殊处理以便防止Activity不能释放。(3)对于背景图(BackgroundDrawable),在Activity的销毁函数中对Activity解除引用。

1.3 本文的研究内容

移动设备的显示特性、交互方式及开发环境与PC机相差很大,如何在受限的硬件条件下开发高性能的绘图平台存在较多技术难题。为了避免在iOS和Android上重复开发、降低移植工作量,需要设计适合多种移动设备的跨平台绘图架构。

因此,本文对下列工作内容进行重点研究和阐述:

(1)设计跨平台的交互式绘图系统架构,适应iOS和Android等多种移动设备的显示特性和多点触摸的交互方式。同时减少重复开发、降低移植工作量。

具体设计方案是抽象出画布接口和视图接口,让跨平台内核与设备平台相关的图形库和界面库分离。设计跨平台的手势分发接口,在设备平台相关的界面适配器中识别手势,并映射到内核的手势分发接口,由内核进行命令转发或放缩计算。

(2)研究iOS上的矢量图形和图像的显示特性和优化方法,实现基于Quartz 2D图形库的高性能的通用交互式绘图平台。涉及多种离屏渲染技术的应用和优化。

(3)基于SWIG和NDK实现Android封装模块(Java)与跨平台内核(C++)的调用和回调扩展,研究并实现基于Android Canvas的矢量图形和图像的高性能显示方法,实现通用交互式绘图平台。

本绘图平台(TouchVG)的矢量图形和绘图功能与传统的CAD等绘图软件类似,在本文中不重点描述。

1.4 论文组织结构

本文共分为下列七章:

第一章,绪论。说明研究的意义、背景、现状,描述了研究的主要内容。

第二章,相关技术介绍。概括本文涉及的核心技术和基础理论。

第三章,移动绘图平台的架构设计。总结移动设备的特点,设计适合移动设备的扩展机制、平台架构、绘图内核模块及设备接口。

第四章,iOS绘图平台的实现。试验iOS上基于Quartz 2D的多种显示技术,总结出性能较高的设计方案。

第五章,Android绘图平台的实现。使用SWIG实现C++内核与Android代码的互操作,实验和总结Android绘图技术,给出实现效果。

第六章,绘图平台的应用和评估。从应用方式和效果、平台对比等多个方面对绘图平台进行了评估和总结。

总结和展望。总结本文的主要工作、创新点和不足,及后续研究工作。


[1] 何高奇. 面向移动设备的图形绘制技术研究[D]. 杭州:浙江大学计算机学院, 2007.

[2] http://www.dajianet.com/digital/2012/0419/185839.shtml

[3] 官酩杰. 基于OpenGL ES的移动平台图形渲染研究与实现[D]. 北京:北京交通大学, 2010.

[4] 沈江. 基于OpenVG的图形绘制关键技术研究[D]. 杭州:杭州电子科技大学, 2010.

[5] 何必仕, 万健, 徐小良. 基于OpenVG矢量图渲染加速研究[J]. 计算机应用与软件, 2010, 27(1):111-113.

[6] 周方晓等. 用GDI+和面向对象设计方法构建交互式图形平台[J]. 微电子学与计算机, 2010, 27(10):165-169.

[7] 鲁力, 李欣. 基于AGG算法库的通用图形接口设计[J]. 微计算机信息, 2009, 25(2):266-267.

[8] 李慧云, 何震苇, 李丽等. HTML5技术与应用模式研究[J]. 电信科学, 2012, 28(5):24-29.

[9] http://www.singaporebim.com/Articles_Oversea/147.html

[10] 杨硕飞. 动态几何画板的研究及其在iPhone平台的实现[D]. 成都:电子科技大学, 2011.

[11] http://stackoverflow.com/questions/10410106/drawing-image-with-coregraphics-on-retina-ipad-is-slow/10424635

[12] http://www.sencha.com/blog/understanding-hardware-acceleration-on-mobile-browsers

[13] http://stackoverflow.com/questions/13277031/core-graphics-performance-on-ios

[14] http://www.jwz.org/blog/2012/07/back-buffering-performance-on-ios-with-quartz

[15] http://stackoverflow.com/questions/11261450/drawrect-with-cgbitmapcontext-is-too-slow

[16] http://stackoverflow.com/questions/11100984/cgcontextdrawlayeratpoint-is-slow-on-ipad-3

[17] http://www.linuxgraphics.cn/android/write_real_time_for_android.html

[18] http://www.extremetech.com/computing/107995-the-truth-about-hardware-acceleration-on-android

[19] http://www.rbgrn.net/content/290-light-racer-20-days-32-33-getting-great-game-performance

[20] http://www.doc88.com/p-78940304236.html

[21] 张江水, 华一新, 唐衡丽等. 嵌入式GIS跨平台技术的研究与实现[J]. 测绘科学技术学报, 2012, 29(3):214-217.

[22] 刘楠, 李欣. 跨平台高质量二维图形库设计与实现[J]. 计算机工程与设计, 2010, 31(7):1599-1622.

[23] Fain G. Curves and surfaces for CAGD: A practical guide, 5th Edition. 2002.

[24] http://processingjs.nihongoresources.com/bezierinfo

[25] http://www.lukew.com/touch

[26] 本研究发现:iOS的长按手势允许有拖动状态,在拖动时相当于“按住并拖动”手势。官方并未宣传此用法。

[27] Epps J. A study of hand shape use in tabletop gesture interaction[A]. Proceedings of CHI EA '06 [C].

[28] http://3g.163.com/coop/ucweb/mobile/11/0312/00/6UTG4KEE00112K95_0.html

[29] 孟祥亮. 显示表面上多触点手势研究[D]. 北京:清华大学计算机科学与技术系, 2010.

[30] 季红艳. 基于多点触摸技术的人机交互研究[D]. 上海:华东师范大学软件学院, 2011.

[31] http://www.aton.com/developing-an-android-mobile-application

[32] http://www.aton.com/android-native-libraries-for-java-applications

[33] Onur Cinar. Pro Android C++ with the NDK. Berkeley: Apress, 2012

[34] http://www.ibm.com/developerworks/cn/java/j-lo-jnileak/index.html

[35] http://blog.gorges.us/2010/07/developing-apps-within-androids-16mb-memory-limit

[36] http://blog.csdn.net/jindegegesun/article/details/8447434

原文地址:https://www.cnblogs.com/rhcad/p/3227994.html