論文第1章:緒論

張雲貴發表於2013-07-31

面向移動裝置的向量繪圖平臺設計與實現

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