轉自:http://blog.sina.com.cn/s/blog_4265e1760100lg03.html
本系列篇章的主要內容是講解矢量圖形庫的編譯、開發和使用。並不對他們周邊的內容做過多的描述,如性能對比等。本人博客所有文章全部都是個人原創,並保留一切權利。不是原創的內容本人一定會注明“轉載”字樣。所以如果您需要轉載,請注明來源,謝謝。
矢量圖形,這是一個非常熟悉但是又讓人覺得陌生的東西。熟悉是因為聽得太多了,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,使用起來才能自由嘛