C# 使用gdi繪製cpu佔用高的問題以及閃爍問題的解決方案

1.問題一,當我們直接在form上連續繪製會出現閃爍的情況!

解決方案:啓用窗體的雙緩衝設置  this.DoubleBuffered = true;或者在構造函數中添加代碼以下代碼即可:

 this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.UserPaint |
                      ControlStyles.AllPaintingInWmPaint, true);

 

2.假設form中有一個panel,此時我需要在窗口加載動態的在panel中添加數量不等的控件,如果不做處理,在加載時也會出現閃爍

解決方案:將panel設置爲雙緩衝控件,添加一個自定義控件,繼承panel,在自定義控件的構造函數中添加代碼

 this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.UserPaint |
                      ControlStyles.AllPaintingInWmPaint, true);

可以解決閃爍問題,如果編譯報錯,刪除報錯行即可!

3.當我開啓雙緩衝後,繪製正常,一切看起來都是那麼完美,但是如果我們查看CPU佔用率會發現很高,並隨我們繪製的快慢和累計時間而也越來越大!我的電腦基本上上會達到30%左右,這在有的場景下是不能容忍的

經測試發現,關閉雙緩衝,cpu佔用率下降一半,但是還是很高!並且會閃爍!

臨時方案1:究其原因,鼠標移動太快,調用Invalidate次數過多,並且太快!  在mouse_move中使用Thread.sleep(10),來控制刷新頻率。當然,界面刷新可能不太流暢!

臨時方案2:如何每次刷新的位置固定和區域固定,使用Invalidate的重載,傳遞區域進去,這樣也可以有效減少CPU佔用!

解決方案:針對連續繪製的問題,首先我們需要禁用掉Form的雙緩衝,然後重載函數OnPaintBackground和Onpaint,

並且註釋掉base,調用,實現手動繪製背景,這樣,我們再繪製時,背景就不會被擦除!同時繪製的時候,我們只繪製相鄰的點,這樣避免重繪所有點,帶來覆蓋和性能損失!在mouse_up時再在OnPaintBackground中繪製背景和所有節點!

當然如果畫布上繪製的對象很多,在刷新背景時,會明顯看到繪製的先後順序。我們可以新建一個bitmap,大小和畫布一致,然然後將所有對象繪製在bitmap上,繪製完成後使用form的gdi將bitmap繪製在form上即可!

關鍵代碼:

                 Bitmap memoryPanel = new Bitmap (this.Width, this.Height);
                Graphics tempg = Graphics.FromImage(memoryPanel);
                tempg.Clear(this.BackColor);
                tempg.SmoothingMode = SmoothingMode.AntiAlias;
                ReDrawAllElement(tempg);
               e.Graphics.DrawImage(memoryPanel, this.ClientRectangle);

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章