午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

C#雙緩沖技術(shù)

 家住天地 2018-07-19
C#雙緩沖技術(shù)

http://hi.baidu.com/jgszhl_85/blog/item/175ada08add768d762d98628.html

GDI+的雙緩沖問(wèn)題終于搞定了, 真是松了一口氣!
一直以來(lái)的誤區(qū):.net1.1 和 .net 2.0 在處理控件雙緩沖上是有區(qū)別的。
.net 1.1 中,使用:this.SetStyle(ControlStyles.DoubleBuffer, true);
.net 2.0中,使用:this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
怪不說(shuō)老是提示參數(shù)無(wú)效,一直也不知道是這個(gè)問(wèn)題,呵呵
要知道,圖元無(wú)閃爍的實(shí)現(xiàn)和圖元的繪制方法沒(méi)有多少關(guān)系,只是繪制方法可以控制圖元的刷新區(qū)域,使雙緩沖性能更優(yōu)!
導(dǎo)致畫(huà)面閃爍的關(guān)鍵原因分析:
      一、繪制窗口由于大小位置狀態(tài)改變進(jìn)行重繪操作時(shí)
     繪圖窗口內(nèi)容或大小每改變一次,都要調(diào)用Paint事件進(jìn)行重繪操作,該操作會(huì)使畫(huà)面重新刷新一次以維持窗口正常顯示。刷新過(guò)程中會(huì)導(dǎo)致所有圖元重新繪制,而各個(gè)圖元的重繪操作并不會(huì)導(dǎo)致Paint事件發(fā)生,因此窗口的每一次刷新只會(huì)調(diào)用Paint事件一次。窗口刷新一次的過(guò)程中,每一個(gè)圖元的重繪都會(huì)立即顯示到窗口,因此整個(gè)窗口中,只要是圖元所在的位置,都在刷新,而刷新的時(shí)間是有差別的,閃爍現(xiàn)象自然會(huì)出現(xiàn)。
     所以說(shuō),此時(shí)導(dǎo)致窗口閃爍現(xiàn)象的關(guān)鍵因素并不在于Paint事件調(diào)用的次數(shù)多少,而在于各個(gè)圖元的重繪。
     根據(jù)以上分析可知,當(dāng)圖元數(shù)目不多時(shí),窗口刷新的位置也不多,窗口閃爍效果并不嚴(yán)重;當(dāng)圖元數(shù)目較多時(shí),繪圖窗口進(jìn)行重繪的圖元數(shù)量增加,繪圖窗口每一次刷新都會(huì)導(dǎo)致較多的圖元重新繪制,窗口的較多位置都在刷新,閃爍現(xiàn)象自然就會(huì)越來(lái)越嚴(yán)重。特別是圖元比較大繪制時(shí)間比較長(zhǎng)時(shí),閃爍問(wèn)題會(huì)更加嚴(yán)重,因?yàn)闀r(shí)間延遲會(huì)更長(zhǎng)。
     解決上述問(wèn)題的關(guān)鍵在于:窗口刷新一次的過(guò)程中,讓所有圖元同時(shí)顯示到窗口。
      二、進(jìn)行鼠標(biāo)跟蹤繪制操作或者對(duì)圖元進(jìn)行變形操作時(shí)
     當(dāng)進(jìn)行鼠標(biāo)跟蹤繪制操作或者對(duì)圖元進(jìn)行變形操作時(shí),Paint事件會(huì)頻繁發(fā)生,這會(huì)使窗口的刷新次數(shù)大大增加。雖然窗口刷新一次的過(guò)程中所有圖元同時(shí)顯示到窗口,但也會(huì)有時(shí)間延遲,因?yàn)榇藭r(shí)窗口刷新的時(shí)間間隔遠(yuǎn)小于圖元每一次顯示到窗口所用的時(shí)間。因此閃爍現(xiàn)象并不能完全消除!
     所以說(shuō),此時(shí)導(dǎo)致窗口閃爍現(xiàn)象的關(guān)鍵因素在于Paint事件發(fā)生的次數(shù)多少。
      解決此問(wèn)題的關(guān)鍵在于:設(shè)置窗體或控件的幾個(gè)關(guān)鍵屬性。
  

下面來(lái)介紹解決辦法的具體細(xì)節(jié):
解決雙緩沖的關(guān)鍵技術(shù):
1、設(shè)置顯示圖元控件的幾個(gè)屬性: 必須要設(shè)置,否則效果不是很明顯!
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |   
                    ControlStyles.ResizeRedraw |
                    ControlStyles.AllPaintingInWmPaint, true);
2、窗口刷新一次的過(guò)程中,讓所有圖元同時(shí)顯示到窗口。
    可以通過(guò)以下幾種方式實(shí)現(xiàn),這幾種方式都涉及到Graphics對(duì)象的創(chuàng)建方式。
Graphics對(duì)象的創(chuàng)建方式:
a、在內(nèi)存上創(chuàng)建一塊和顯示控件相同大小的畫(huà)布,在這塊畫(huà)布上創(chuàng)建Graphics對(duì)象。
     接著所有的圖元都在這塊畫(huà)布上繪制,繪制完成以后再使用該畫(huà)布覆蓋顯示控件的背景,從而達(dá)到“顯示一次僅刷新一次”的效果!
  實(shí)現(xiàn)代碼(在OnPaint方法中):
  Rectangle rect = e.ClipRectangle;
  Bitmap bufferimage = new Bitmap(this.Width, this.Height);
      Graphics g = Graphics.FromImage(bufferimage);
  g.Clear(this.BackColor);
      g.SmoothingMode = SmoothingMode.HighQuality; //高質(zhì)量
      g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移質(zhì)量
  foreach (IShape drawobject in doc.drawObjectList)
       {
                  if (rect.IntersectsWith(drawobject.Rect))
                {
                    drawobject.Draw(g);
                    if (drawobject.TrackerState == config.Module.Core.TrackerState.Selected
                        && this.CurrentOperator == Enum.Operator.Transfrom)//僅當(dāng)編輯節(jié)點(diǎn)操作時(shí)顯示圖元熱點(diǎn)
                    {
                        drawobject.DrawTracker(g);
                     }
                }

        }
    using (Graphics tg = e.Graphics)
            {
                tg.DrawImage(bufferimage, 0, 0);  //把畫(huà)布貼到畫(huà)面上
            }
b、直接在內(nèi)存上創(chuàng)建Graphics對(duì)象:
     Rectangle rect = e.ClipRectangle;
     BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
            BufferedGraphics myBuffer = currentContext.Allocate(e.Graphics, e.ClipRectangle);
            Graphics g = myBuffer.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
            g.Clear(this.BackColor);
            foreach (IShape drawobject in doc.drawObjectList)
            {
                if (rect.IntersectsWith(drawobject.Rect))
                {
                    drawobject.Draw(g);
                    if (drawobject.TrackerState == config.Module.Core.TrackerState.Selected
                        && this.CurrentOperator == Enum.Operator.Transfrom)//僅當(dāng)編輯節(jié)點(diǎn)操作時(shí)顯示圖元熱點(diǎn)
                    {
                        drawobject.DrawTracker(g);
                     }
                }
            }
    myBuffer.Render(e.Graphics);
            g.Dispose();
            myBuffer.Dispose();//釋放資源
至此,雙緩沖問(wèn)題解決,兩種方式的實(shí)現(xiàn)效果都一樣,但最后一種方式的占有的內(nèi)存很少,不會(huì)出現(xiàn)內(nèi)存泄露!
參考資料:
2、GDI+圖形程序設(shè)計(jì)   [美]Mahesh Chand 著       電子工業(yè)出版社
3、C#高級(jí)編程(第三版)
-------------------------------------------------
在使用了bitmap繪制下,可以簡(jiǎn)單的設(shè)置this.SetStyle(ControlStyles.Opaque, true);,就可以去除閃爍,設(shè)置這個(gè)參數(shù)指明窗體是不負(fù)責(zé)在后臺(tái)繪制自己的,如果這個(gè)屬性設(shè)置了,那么必須為清除和重繪操作添加相關(guān)的代碼。即必須添加g.Clear(this.BackColor);
適當(dāng)?shù)慕M合使用區(qū)域和智能重繪你可以編寫(xiě)出運(yùn)行速度快且不會(huì)引起閃爍的繪制代碼,并且比單獨(dú)使用雙重緩沖區(qū)繪制還要節(jié)省內(nèi)存的消耗。
即在繪制前,使用OnPaintBackground和OnPaint事件,各自繪制出需要繪制的部分,其他部分不繪制
兩種方法:(傳說(shuō)第二種方式的占有的內(nèi)存很少,不會(huì)出現(xiàn)內(nèi)存泄露?。?/DIV>
1:
private void drawDoubleBuffer1(PaintEventArgs e)
{
    if (!_isDataReady)
    {
        return;
    }
 
    _backBitmap = new Bitmap(this.Width, this.Height);
    Graphics g = Graphics.FromImage(_backBitmap);
    draw(g);
 
    _isDataReady = false;
    e.Graphics.DrawImage(_backBitmap, 0, 0);
}

  

2:
private void drawDoubleBuffer2(PaintEventArgs e)
{
    if (!_isDataReady)
    {
        return;
    }
 
    BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
    BufferedGraphics myBuffer = currentContext.Allocate(e.Graphics, e.ClipRectangle);
    draw(myBuffer.Graphics);
 
    myBuffer.Render(e.Graphics);
    myBuffer.Dispose();
    currentContext.Dispose();
 
    _isDataReady = false;
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多