繪圖效率完整解決方案——三種手段提高GDI/GDI+繪圖效率


現在的cpu飛快,其實數學計算一般很快,cpu大部分時間是在處理繪圖,而繪圖有三種境界:1>每次重繪整體Invalidate(); 2>每次局部繪制Invalidate(Rect); 3>有選擇的局部繪制。

  不能說,一定是第三種方式好,得視情況,境界高程序肯定就復雜,如果對效率要求不高或者繪圖量小當然直接用第一種方式。然而,稍微專業點的繪圖程序,第一第二種方式肯定滿足不了要求,必須選用第三種方式。而第三種方式的手段多樣,也得根據實際情況拿相應的解決之道。這里講解一般的三種手段,他們可以聯合使用。

1. 緩存——Bitmap或者DoubleBuffer。緩存就是先把繪制的圖形繪制到一張內存位圖上,然后在一次性的貼位圖,他可以提高繪圖速度,也能避免閃爍。DoubleBuffer=true是C#窗體的屬性,設置了此屬性估計系統本身會起用無效區的內存位圖緩存,而不需要程序員Bitmap處理。

2. 合理利用無效區域。無效區域就是系統保存當前變化需要重繪的區域,可以在OnPaint()中,e.ClipRectangle直接獲得,也可以通過其他方式獲得。Windows系統只會重繪無效區域內的繪圖信息,然而我們用戶的繪制代碼一般是繪制整個區域的,很多時候無效區域只是一小部分區域,雖然執行了所有的繪圖代碼,但是Windows系統只會重新更新無效區域內的繪圖。這里有兩個利用點:1>用戶請求重繪時,只請求重繪指定區域的,而不是整個區域,如Invalidate(Rect);2>在用戶繪圖代碼Graphics g; g.DrawLine\g.DrawString\g.FillRectangle...前,先判斷繪圖的內容是否在無效區域,如果不是就不直接g.Draw...繪圖代碼。

3. 直接貼圖。一般繪圖或者重繪是Windows根據無效區域繪制的,如果在鼠標移動時需要重繪通過Windows系統處理Paint消息,有時滿足不了要求,比如①鼠標移動繪制十字測量線就得用異或線而不是Paint消息,又比如②鼠標移動繪制跟隨的信息提示框需要頻繁擦除上次覆蓋的背景,又比如③台球滾動時台球與球桌背景的關系。類似的這些問題如何解決?首先肯定不能利用Windows原來的繪圖機制。其中一種解決方式是,不斷的幀間變化區域貼內存位圖——②中的信息框每次鼠標位置變化時可以重新g.Draw...或者貼早生成的信息框內存位圖,②中被信息框覆蓋的背景應該把本來的大背景截取此需要擦除區域的位置大小位圖貼回來就是擦除背景了。由於每次大背景發生變化時,都應會重新生成大背景內存位圖,所以可以是變化的背景。

  這三種方式可以一起使用,應該可以解決中等的繪圖項目的效率問題。中大型的繪圖,必須記住兩點1>只繪制電腦屏幕能顯示的部分;2>只繪制變化的部分。

版權聲明:本文為博主原創文章,未經博主允許不得轉載。


免責聲明!

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



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