1. 程式人生 > >C++向量圖形庫系列(1)——向量圖形庫亂談

C++向量圖形庫系列(1)——向量圖形庫亂談

 本系列篇章的主要內容是講解向量圖形庫的編譯、開發和使用。並不對他們周邊的內容做過多的描述,如效能對比等。本人部落格所有文章全部都是個人原創,並保留一切權利。不是原創的內容本人一定會註明“轉載”字樣。所以如果您需要轉載,請註明來源,謝謝。

    向量圖形,這是一個非常熟悉但是又讓人覺得陌生的東西。熟悉是因為聽得太多了,Flash就大量應用了向量圖形技術,得以讓一段完整的動畫檔案體積相比以逐幀圖片流的媒體格式要小得多,並且畫質無損,這也是在早期的網際網路上快速傳播開去讓使用者接受的基礎(檔案體積不能太大,否則誰也沒有心思等著一點點的下載……)。陌生則是因為很多人搞了若干年的Win32軟體開發,翻來覆去就是MFC/GDI/Socket……,似乎啥時也沒有向量圖形技術的事情。

    但是,不得不承認,Win32的GDI不論是在速度上還是在功能上,都已經是脫離時代了,所以GDI 滿有信心的出來了。有些人可能搞不太清楚GDI和GDI 的關係,我也經常聽到一些程式說用GDI 取代GDI。實際上的情況是:GDI 不過是一套C 的庫,其底層仍舊與GDI有那麼點千絲萬縷的聯絡。如果說GDI能在不同的顯示裝置上依據驅動而獲得加速的話,GDI 就只能是依據不同的CPU平臺的運算速度而獲得加速了——因為他是一套硬體無關的C 圖形庫,大量的圖形演算法是其核心的內容。

    儘管GDI 出來已經有些年頭了,但是似乎使用者卻不多(至少我沒有看見我身邊的朋友什麼的使用過)。我曾為這個問題做過一些調查,有人說他用過GDI ,但是感覺速度好像很慢,還不如自己寫的程式碼。也有人說感覺用不上,又不天天做畫圖軟體。還有人說GDI用習慣了,GDI 用著彆扭也沒發現啥優勢…………的確,這些感覺我也曾經存在過,所以我也不是太喜歡用GDI ,速度也的確不是太快——至少我自己做的GDI 畫圖板,在我的電腦1920*1080解析度下全屏雙快取連續填充圖形的時候,效能的確是不高(已經儘可能的優化)。如果再用上ColorMatrix的話,我那可憐的四核也跟過了時的機器一樣,跑得實在困難。

    所以,我需要給各位介紹一些新的大牛了,其實也不是什麼新的東西,有些都是N久的名牌,穩定工作很多年,用於過很多的專案了。這些大牛們跟GDI 的功能上都極其類似(一般還是會要多一些東西的),功能類似的意思是GDI 有的,他們都可以實現,他們有的,GDI 也都可以搞出來。但在效能上或者影象質量上卻有著各不相同的表現了。比如大名鼎鼎的Cairo、AGG以及Google放出來的Skia(這三個從知名度上來講基本可以算是三足鼎立了,呵呵),另外還有一些不太知名的(不知名不意味著他不強大),比如商業庫DISLIN,還有PHP用的GD等,甚至還有一些聯絡並不緊密的CImg(這個準確來講應當是屬於圖形處理庫,而不是向量圖形庫了,但是很多網站都喜歡把他們列舉到一起,嚴格來說的話,不太好理解)。

    不過本系列篇章的主要目的,是說適量圖形庫,所以多餘的就不說了,我們從Cairo開始說起。

    大名鼎鼎的Cairo,官網:http://www.cairographics.org,開源社群的精品專案之一,已經基本上成為了Linux下的圖形標準。Firefox的底層繪圖就是用的Cairo。關於Cairo更多的東西,Google一下吧,會比我說得更詳細,呵呵。

    AGG,官網:http://www.antigrain.com/,也是比較出名的向量繪相簿了,僅僅只是看官方站上的下載的Demo,都會有點酷酷的感覺:)。使用起來與Cairo最大區別就是AGG更像是一堆未緊密聯絡的class,屬於弱藕合狀態,並且大量的使用了C 模板技術,從使用者的角度來看,AGG的難度是不小的,因為他只是給你提供了一系列的功能塊,怎麼組合使用,還全在使用者自己,而Cairo則提供了相對比較簡單明瞭的C函式介面。因此也就出現了AggPlus專案,他的目的就是把AGG包裝一次,並且是使用的仿GDI 類似介面。如果使用AggPlus的話,有GDI 相關經驗的就容易使用了,不過貌似效能也就有了不小的下降。

    關於Cairo和AGG的效能對比,Google一下就能找到詳細的內容,但是簡單的說一下,就繪圖方面的速度來看,我的經驗是Cairo的速度會比AGG快,尤其是Cairo已經出了1.9版,提速較大。AGG則完全依賴C ,沒有硬體加速。他比較聰明的一個地方就是在光柵的時候使用了整數運算而不是浮點數運算。AGG在官網上宣稱其生成的影象質量要比GDI 高,從我的實際使用經驗來看也的確是這樣的。這個Google也能找到例項,本處不再多說。

    最後是Skia。其實Skia是原本應該是商業專案,讓Google收購之後給開源了,官網:http://code.google.com/p/skia/,授權形式是Apache 2.0,這個授權形式比較的爽,呵呵。Skia的速度不在Cairo和AGG之下,而介面形式的複雜度相對Cairo稍微高一點,比AGG要容易。功能則基本上沒有太大的差別。不過如果要說程式碼的清晰度的話,Skia也是這3個專案中最好的,我很快就能熟悉Skia的程式碼並對其做出我所需要的修改。所以目前我個人是比較喜歡Skia的。從Cairo轉到AGG再轉到Skia,現在就一直使用Skia了。

    在這些向量圖形庫裡,有一些東西是大家一般都支援但是GDI 沒有的,比如對於SVG或PostScript的支援,比如大家都可以跨平臺但GDI 不可以等等。另外,Cairo還有一個很明顯的優點是其它一些庫所不具備的,就是Cairo支援數量眾多的Backends,其實就是BackBuffer或者叫DrawTarget的東西,Cairo可以直接把要繪製的內容畫到Win32 GDI Bitmap/DC、PDF、SVG、PostScript、OpenGL、Printer等眾多的Target上,這是Cairo的一大特色,據說也是Firefox選擇Cairo的一個重要理由。如果你的應用程式是需要將圖形內容繪製到各種各樣不同的Target的時候,選擇Cairo的確可以省掉不少的事情。

    好了,亂談就到此為止吧。本篇是開篇,下一篇,我們將一起來嘗試使用VC來編譯Cairo(1.8.x版),這是一切使用的大前提嘛,畢竟用VC在Win32上做軟體開發的還是多數的。但是編譯Cairo就讓不少人碰到了問題。所以我們先解決了編譯的問題,包括再下一篇我計劃講解Skia在VC上的編譯。編譯出了Lib/DLL,使用起來才能自由嘛C++向量圖形庫系列(1)鈥斺斒噶客夾慰飴姨