亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#雙緩沖技術實例詳解

2020-01-24 01:15:30
字體:
來源:轉載
供稿:網友

本文實例分析了C#雙緩沖技術。分享給大家供大家參考,具體如下:

雙緩沖解決閃爍問題。

整理:

GDI+的雙緩沖問題

一直以來的誤區:.net1.1 和 .net 2.0 在處理控件雙緩沖上是有區別的。
.net 1.1 中,使用:this.SetStyle(ControlStyles.DoubleBuffer, true);
.net 2.0中,使用:this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
導致畫面閃爍的關鍵原因分析:

一、繪制窗口由于大小位置狀態改變進行重繪操作時

繪圖窗口內容或大小每改變一次,都要調用Paint事件進行重繪操作,該操作會使畫面重新刷新一次以維持窗口正常顯示。刷新過程中會導致所有圖元重新繪制,而各個圖元的重繪操作并不會導致Paint事件發生,因此窗口的每一次刷新只會調用Paint事件一次。窗口刷新一次的過程中,每一個圖元的重繪都會立即顯示到窗口,因此整個窗口中,只要是圖元所在的位置,都在刷新,而刷新的時間是有差別的,閃爍現象自然會出現。

所以說,此時導致窗口閃爍現象的關鍵因素并不在于Paint事件調用的次數多少,而在于各個圖元的重繪。

根據以上分析可知,當圖元數目不多時,窗口刷新的位置也不多,窗口閃爍效果并不嚴重;當圖元數目較多時,繪圖窗口進行重繪的圖元數量增加,繪圖窗口每一次刷新都會導致較多的圖元重新繪制,窗口的較多位置都在刷新,閃爍現象自然就會越來越嚴重。特別是圖元比較大繪制時間比較長時,閃爍問題會更加嚴重,因為時間延遲會更長。

解決上述問題的關鍵在于:窗口刷新一次的過程中,讓所有圖元同時顯示到窗口。

二、進行鼠標跟蹤繪制操作或者對圖元進行變形操作時

當進行鼠標跟蹤繪制操作或者對圖元進行變形操作時,Paint事件會頻繁發生,這會使窗口的刷新次數大大增加。雖然窗口刷新一次的過程中所有圖元同時顯示到窗口,但也會有時間延遲,因為此時窗口刷新的時間間隔遠小于圖元每一次顯示到窗口所用的時間。因此閃爍現象并不能完全消除!

所以說,此時導致窗口閃爍現象的關鍵因素在于Paint事件發生的次數多少。

解決此問題的關鍵在于:設置窗體或控件的幾個關鍵屬性

使用雙緩沖

解決雙緩沖的關鍵技術:

1、設置顯示圖元控件的幾個屬性:  必須要設置,否則效果不是很明顯!

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

2、窗口刷新一次的過程中,讓所有圖元同時顯示到窗口。

可以通過以下幾種方式實現,這幾種方式都涉及到Graphics對象的創建方式。

具體實現

1、利用默認雙緩沖

(1)在應用程序中使用雙緩沖的最簡便的方法是使用 .NET Framework 為窗體和控件提供的默認雙緩沖。通過將 DoubleBuffered 屬性設置為 true。

this.DoubleBuffered=true;

(2)使用 SetStyle 方法可以為 Windows 窗體和所創作的 Windows 控件啟用默認雙緩沖。

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

2、手工設置雙緩沖

.netframework提供了一個類BufferedGraphicsContext負責單獨分配和管理圖形緩沖區。每個應用程序域都有自己的默認 BufferedGraphicsContext 實例來管理此應用程序的所有默認雙緩沖。大多數情況下,每個應用程序只有一個應用程序域,所以每個應用程序通常只有一個默認 BufferedGraphicsContext。默認 BufferedGraphicsContext 實例由 BufferedGraphicsManager 類管理。通過管理BufferedGraphicsContext實現雙緩沖的步驟如下:

(1)獲得對 BufferedGraphicsContext 類的實例的引用。

(2)通過調用 BufferedGraphicsContext.Allocate 方法創建 BufferedGraphics 類的實例。

(3)通過設置 BufferedGraphics.Graphics 屬性將圖形繪制到圖形緩沖區。

(4)當完成所有圖形緩沖區中的繪制操作時,可調用 BufferedGraphics.Render 方法將緩沖區的內容呈現到與該緩沖區關聯的繪圖圖面或者指定的繪圖圖面。

(5)完成呈現圖形之后,對 BufferedGraphics 實例調用釋放系統資源的 Dispose 方法。

完整的例子,在一個400*400的矩形框內繪制10000個隨機生成的小圓。

BufferedGraphicsContext current = BufferedGraphicsManager.Current; //(1)BufferedGraphics bg;bg = current.Allocate(this.CreateGraphics(),this.DisplayRectangle); //(2)Graphics g = bg.Graphics;//(3)//隨機 寬400 高400System.Random rnd = new Random();int x,y,w,h,r,i;for (i = 0; i < 10000; i++){    x = rnd.Next(400);    y = rnd.Next(400);    r = rnd.Next(20);    w = rnd.Next(10);    h = rnd.Next(10);    g.DrawEllipse(Pens.Blue, x, y, w, h);}bg.Render();//(4)//bg.Render(this.CreateGraphics());bg.Dispose();//(5)

3、自己開辟一個緩沖區(如一個不顯示的Bitmap對象),在其中繪制完成后,再一次性顯示。

完整代碼如下:

Bitmap bt = new Bitmap(400, 400);Graphics bg = Graphics.FromImage(bt);System.Random rnd = new Random();int x, y, w, h, r, i;for (i = 0; i < 10000; i++){    x = rnd.Next(400);    y = rnd.Next(400);    r = rnd.Next(20);    w = rnd.Next(10);    h = rnd.Next(10);    bg.DrawEllipse(Pens.Blue, x, y, w, h);}this.CreateGraphics().DrawImage(bt, new Point(0, 0)); 

另外一個例子,差不多

Graphics對象的創建方式:

a、在內存上創建一塊和顯示控件相同大小的畫布,在這塊畫布上創建Graphics對象。

接著所有的圖元都在這塊畫布上繪制,繪制完成以后再使用該畫布覆蓋顯示控件的背景,從而達到“顯示一次僅刷新一次”的效果!

實現代碼(在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; //高質量g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移質量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)//僅當編輯節點操作時顯示圖元熱點      {        drawobject.DrawTracker(g);      }    }}using (Graphics tg = e.Graphics){    tg.DrawImage(bufferimage, 0, 0);//把畫布貼到畫面上}

b、直接在內存上創建Graphics對象:

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)//僅當編輯節點操作時顯示圖元熱點      {        drawobject.DrawTracker(g);      }    }}myBuffer.Render(e.Graphics);g.Dispose();myBuffer.Dispose();//釋放資源

至此,雙緩沖問題解決,兩種方式的實現效果都一樣,但最后一種方式的占有的內存很少,不會出現內存泄露!

接下來是對acdsee拖動圖片效果的實現。開始不懂雙緩沖,以為雙緩沖可以解決這個問題,結果發現使用了雙緩沖沒啥效果,請教了高人,然后修改了些代碼,完成這個效果。

圖片是在pictureBox1里。

Bitmap currentMap;bool first = true;private void pictureBox1_MouseDown(object sender, MouseEventArgs e){  if (zoom == 0)  {    if (e.Button == MouseButtons.Left) //dragging      mousedrag = e.Location;    Image myImage = myMap.GetMap();    currentMap = new Bitmap(myImage);    first = false;  }}private void pictureBox1_MouseMove(object sender, MouseEventArgs e){  if (zoom == 0&&!first)  {      Image img = new Bitmap(Size.Width, Size.Height);      Graphics g = Graphics.FromImage(img);      g.Clear(Color.Transparent);//圖片移動后顯示的底色      g.SmoothingMode = SmoothingMode.HighQuality; //高質量      g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移質量      g.DrawImageUnscaled(currentMap, new System.Drawing.Point(e.Location.X - mousedrag.X, e.Location.Y - mousedrag.Y));//在g中移動圖片,原圖在(0,0)畫的,所以直接用new System.Drawing.Point(e.Location.X - mousedrag.X, e.Location.Y - mousedrag.Y)就好。      g.Dispose();      pictureBox1.Image = img;//img是在鼠標這個位置時生成被移動后的暫時的圖片  }}private void pictureBox1_MouseUp(object sender, MouseEventArgs e){  if (zoom == 0)  {    System.Drawing.Point pnt = new System.Drawing.Point(Width / 2 + (mousedrag.X - e.Location.X),    Height / 2 + (mousedrag.Y - e.Location.Y));    myMap.Center = myMap.ImageToWorld(pnt);    pictureBox1.Image = myMap.GetMap();    first = true;  }}

說說思路,在鼠標點下時創建一個bitmap,currentMap,用它來存放當前圖像。鼠標移動時,根據鼠標位置畫圖,最后,鼠標up時,重新畫圖。

更多關于C#相關內容感興趣的讀者可查看本站專題:《C#面向對象程序設計入門教程》、《C#常見控件用法教程》及《C#數據結構與算法教程

希望本文所述對大家C#程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美美女15p| 91精品久久久久久久| 亚洲第一区中文99精品| 国产在线观看一区二区三区| 久久手机免费视频| 91精品中文在线| 亚洲级视频在线观看免费1级| 久久久久久亚洲精品不卡| 久久国产精品电影| 欧美色另类天堂2015| 欧美亚洲午夜视频在线观看| 欧美一区二区三区艳史| 久久99久久99精品中文字幕| 久久噜噜噜精品国产亚洲综合| 91性高湖久久久久久久久_久久99| 激情成人中文字幕| 亚洲精品久久久久中文字幕欢迎你| 国产精品99久久久久久白浆小说| 精品精品国产国产自在线| 亚洲区中文字幕| 亚洲精品日韩激情在线电影| 久久综合国产精品台湾中文娱乐网| 亚洲第一视频在线观看| 亚洲国产99精品国自产| 亚洲经典中文字幕| 日韩高清不卡av| 久久久亚洲福利精品午夜| 中文字幕av日韩| 4438全国亚洲精品在线观看视频| 亚洲网址你懂得| 国产亚洲成av人片在线观看桃| 国产精品久在线观看| 97精品免费视频| 精品久久久久久久久国产字幕| 国产精品影片在线观看| 青草青草久热精品视频在线观看| 欧美—级a级欧美特级ar全黄| 亚洲精品久久7777777| 色悠悠久久88| 亚洲男子天堂网| 91大神在线播放精品| 日韩风俗一区 二区| 成人淫片在线看| 国产精品美女久久| 亚洲网站视频福利| 欧美极品少妇xxxxⅹ免费视频| 成人黄色av网站| 国产97在线播放| 国产精品中文字幕久久久| 亚洲国产99精品国自产| 国产一区二区三区久久精品| 亚洲日本成人女熟在线观看| 国产精品高潮呻吟久久av黑人| 亚洲欧洲在线视频| 国产成人亚洲精品| 亚洲综合大片69999| xvideos成人免费中文版| 日本欧美国产在线| 一本一道久久a久久精品逆3p| 欧美精品videofree1080p| 在线观看不卡av| 色偷偷综合社区| 色偷偷偷亚洲综合网另类| 久久久久久国产免费| 国产视频精品va久久久久久| 自拍偷拍亚洲区| 在线观看日韩专区| 97精品国产97久久久久久春色| 日韩精品中文字| 亚洲最大av在线| 97视频免费在线观看| 久久久久中文字幕| 久久精品这里热有精品| 国产成人一区二区三区电影| 亚洲欧美综合v| 日韩中文字幕在线看| 国产成人自拍视频在线观看| 精品国产乱码久久久久久虫虫漫画| 精品国内产的精品视频在线观看| 北条麻妃99精品青青久久| 91精品国产成人www| 欧美人成在线视频| 神马久久桃色视频| 国产精品v日韩精品| 欧美专区在线播放| 国产福利精品在线| 91精品国产综合久久久久久久久| 日韩欧美中文字幕在线观看| 亚洲人成电影网| 亚洲图片欧洲图片av| 国产男人精品视频| 亚洲国产精久久久久久久| 国产999在线| 伦伦影院午夜日韩欧美限制| 亚洲精品女av网站| 国内精品久久久久| 国产精品扒开腿做爽爽爽男男| 色琪琪综合男人的天堂aⅴ视频| 狠狠躁夜夜躁久久躁别揉| 日韩中文在线中文网三级| 国产成人精品日本亚洲专区61| 欧美丰满少妇xxxxx做受| 日韩成人av网| 日韩精品免费观看| 亚洲精品xxxx| 亚洲国产另类 国产精品国产免费| 在线观看国产精品淫| 中文字幕无线精品亚洲乱码一区| 国内揄拍国内精品少妇国语| 欧美xxxx14xxxxx性爽| 国产精品777| 色噜噜国产精品视频一区二区| 亚洲免费电影在线观看| 久久久久久久香蕉网| 亚洲一区第一页| 亚洲国产精品va在看黑人| 久久久久久国产免费| 久久久久久伊人| 亚洲自拍欧美另类| 中文字幕一精品亚洲无线一区| 欧美色另类天堂2015| 国产一区红桃视频| 欧美www视频在线观看| 亚洲男人天堂网站| 亚洲美女激情视频| 亚洲jizzjizz日本少妇| 欧美激情亚洲自拍| 亚洲男人天堂久| 最近2019中文字幕mv免费看| 久久影视三级福利片| 亚洲欧美日韩天堂一区二区| 国产精品免费视频xxxx| 亚洲免费视频在线观看| 日韩最新在线视频| 2019中文字幕免费视频| 久久久亚洲影院你懂的| 日韩视频在线免费| 欧美激情精品久久久久久黑人| 日韩三级影视基地| 97激碰免费视频| 最近日韩中文字幕中文| 欧美极品美女电影一区| 亚洲国产精品成人va在线观看| 91成人在线视频| 最近日韩中文字幕中文| 18一19gay欧美视频网站| 国产精品自产拍在线观看| 精品美女国产在线| 久久久久久97| 欧美在线亚洲一区| 91高潮在线观看| 亚洲成人免费网站| 国产91亚洲精品| 中文字幕日韩欧美在线| 精品一区二区三区电影| 日韩精品在线观看一区二区| 午夜精品一区二区三区在线播放| 国产丝袜一区二区三区| 亚洲国产毛片完整版| 国产成人亚洲精品| 在线性视频日韩欧美| 中文字幕久久久| 影音先锋欧美精品| 欧美激情国内偷拍|