雜談SharpDx中的WIC組件——我們需要WIC的圖片編碼功能么?


在前文 SharpDX之Direct2D教程II——加載位圖文件和保存位圖文件 中,發現在VB2010中不能很好的運用SharpDx中的WIC組件進行圖片的編碼工作。可能是我的設置問題,也可能是SharpDx對VB2010支持的不夠好(用C#就沒有問題) ,有網友將代碼貼到VB2012中,也發現可以運行的很好。由於手頭上沒有VS2012,故這個功能的實驗放置一段時間

 

不過,回過頭想一想。我們需要WIC的圖片編碼功能么?

 

Direct2D(SharpDx等)的顯示繪制優勢

和GDI、GDI+相比,Direct2D(SharpDx等)的優勢在於利用硬件(GPU)繪制,節省時間,節省CPU的占用率,提高繪制效率。

 

GDI、GDI+等的繪制流程如下:

1、GDI、GDI+將繪制命令傳到CPU

2、CPU開始在內存中繪制圖形

3、CPU將繪制完的圖形傳到GPU

4、GPU將圖形傳到顯示設備(顯示器等)

 

Direct2D(SharpDx等)的繪制模式有Hardware(基於硬件)、Software(基於軟件)、Default(默認)

其中Software模式和GDI、GDI+繪制流程一樣。Default模式在初始化的時候會進行硬件檢測,如果硬件支持,則采用Hardware模式,如果硬件不支持,則采用Software模式

 

Direct2D(SharpDx等)在模式選擇為Hardware時的繪制流程如下:

1、Direct2D(SharpDx等)將繪制命令傳到CPU

2、CPU將繪制命令傳到GPU

3、GPU在顯存中繪制圖形

4、GPU將繪制好的圖形傳到顯示設備(顯示器等)

 

上述兩個流程的區別在於:

GDI、GDI+等是利用CPU繪制圖形,繪制圖形在內存中有備份。

Direct2D(SharpDx等)的Hardware模式是利用GPU繪制圖形,內存中並沒有備份。和GDI、GDI+等相比優勢在於快,節省CPU占用(GPU的繪制效率遠高於CPU)。但也有一些問題,就是CPU將繪制命令傳到GPU后,就不管了,至於GPU繪制成什么樣子,那就是GPU的事了。這也可以解釋為何早期的顯卡,有時會出現渲染的錯誤。

 

WIC如何將繪制的圖形編碼到圖形文件

在Direct2D的說明幫助里提到,如果需要利用WIC將RenderTarget上的內容編碼到圖形文件中的話,則得把RenderTarget的模式設置為Software(不能是Hardware,以目前的電腦配置Default基本上等同於Hardware)

 

WIC將RenderTarget上的內容編碼到圖形文件的流程如下:

1、創建WicBitmap對象,再之上創建WicRenderTarget對象

2、創建D2DBitmap對象,再利用CopyFromRenderTarget方法把RenderTarget上的內容復制到D2DBitmap對象

3、利用WicRenderTarget對象的DrawBitmap方法把D2DBitmap對象繪制到WicBitmap對象上

4、創建BitmapEncoder對象,在之上創建BitmapFrameEncoder對象,並創建和BitmapEncoder相關的Stream對象

5、將WicBitmap對象寫入到BitmapFrameEncoder對象

6,調用BitmapFrameEncoder對象和BitmapEncoder對象的Commit方法,將內容編碼到Stream對象,可以保存到文件

 

在Software模式下,是利用CPU繪制圖形,結果在內存中有緩存。WIC的WicRenderTarget對象的DrawBitmap方法能把緩存中的內容繪制到WicBitmap上。

而在Hardware模式下,利用的是GPU繪制圖形,在內存中沒有緩存。WIC的WicRenderTarget對象的DrawBitmap方法沒法把內容繪制到WicBitmap上(因為緩存中沒有),強行調用的話,會報錯的。

 

 

 

我們需要WIC的圖片編碼功能么?

用Direct2D(SharpDx等)就是看重其硬件加速的能力,但也籍此不能使用WIC保存繪制的內容;如果要使用WIC保存繪制的內容,則Direct2D(SharpDx等)的繪制模式設置為Software,但又犧牲了硬件加速能力,其效率和GDI、GDI+等相差無幾。

 

再加上WIC實際上是調用系統默認的編碼器對圖形進行編碼,但同時幾乎不提供的可調參數的功能。例如:我們知道在保存JPG的時候,可以設置精度(因為JPG是有損壓縮,根據精度的不同,保存的文件大小也不相同),但是用WIC保存為JPG的時候,卻沒有參數可以設置精度(或者是我沒找到);保存為GIF時,可以設置每幀之間的間隔時間,但在WIC中也沒有相應的屬性可以提供(也許可以通過添加MetaData的方式設置該屬性)。

 

換個角度考慮,圖形的編碼遠比解碼復雜的多。解碼圖形,只要依據已經存在的數據按照一定的規則解碼就行了,即使是用不同的解碼器解碼出來的圖形應該是毫無二致。但是,編碼就不同了,同樣的格式、同樣的參數,不同的編碼器出來的文件可能就不一樣了(我們用PS和Fireworks編碼出來的GIF文件大小就不一樣)。

 

因此,如果是采用默認編碼器對圖形編碼的話,真不一定需要WIC(WIC僅僅是提供了一個調用的途徑),在GDI+中完全可以利用Bitmap對象的Save方法做到。如果需要對編碼進行參數設置的話,以獲得不同的文件的話,這個似乎WIC又做不到。

 

 

 

因此,看來我們並不需要WIC的圖片編碼功能。再說,我們使用Direct2D(SharpDx等)是依靠其硬件加速的能力,加強圖形渲染功能。

 

現在在研究GIF的編碼,發現 Robin 寫的系列文章不錯。待研究后再書新文


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM