C 下實現雙緩衝描畫高頻曲線 GDI 結合GDI

2021-04-21 04:11:16 字數 3631 閱讀 4218

由於專案需要,要使用c#描畫高頻實時曲線.

但是在c#下由於描畫影象使用的是gdi+,描畫效率很有問題.一旦曲線太多,就會造成cpu使用率直線上公升,馬上飆公升到100%.

在gdi+下使用雙緩衝也無濟於事,雙緩衝本身只會解決曲線多的時候全屏閃爍問題,但描畫效率還是嚴重低下.

其間用過多種解決方案:drect3d,drirect2d,gdi,,,,,等等等等

最後從效率出發,最終解決方案如下:

前台顯示使用gdi,而後台描畫則採用gdi+

後台採用10倍於前台視窗的buffer,每次向其中畫一條線.然後通過乙個rect視口,每次向前臺顯示視口裡的內容.否則每次重繪的代價太高.

這個方法實現的難點主要在於gdi和gdi+的結合部分,主要**如下:

1.函式庫:using 和 win32api函式

using system.runtime.interopservices;

using system.drawing;

using system.drawing.imaging;

using system.drawing.drawing2d;

using system.drawing.text;

[dllimport("gdi32")]

public

static

extern intptr createcompatibledc(intptr hdc);

[dllimport("gdi32")]

public

static

extern intptr selectobject(intptr hdc, intptr hobject);

[dllimport("gdi32.dll")]

public

static

extern

long bitblt(intptr hdcdest, int nxdest, int nydest, int nwidth, int nheight, intptr hdcsrc, int nxsrc, int nysrc, int dwrop);

[dllimport("gdi32.dll")]

public

static

extern

bool deleteobject(intptr hobject);

2.宣告物件

public picturebox _backgroundgraph;//被描畫的控制項物件

//public form _backgroundgraph;

public graphics _backgroundgraphic = null; // 背景graphic

public graphics _backgroundrendergraphic = null; // 雙緩衝graphic

private graphics _backgroundmemorygraphic = null; // 記憶體graphic

public graphics _backgrounddrawgraphic = null; // 描畫graphic

private bitmap _backgroundmemorybitmap = null; // 記憶體bitmap

public bufferedgraphics _graphicsbuffer = null; // 雙緩衝bufferedgraphics

private intptr _memorygraphichdc; // 記憶體graphic適用的引用

private intptr _memorybitmaphdc; // 記憶體bitmap適用的引用

3.初始化物件

public

void initdraw()

if (null != _graphicsbuffer)

if (null != _backgroundrendergraphic)

if (null != _backgroundmemorybitmap)

if (null != _backgroundmemorygraphic)

if (null != _backgrounddrawgraphic)

// 背景graphic

_backgroundgraphic = _backgroundgraph.creategraphics();

bufferedgraphicscontext currentcontext = bufferedgraphicsmanager.current;

_graphicsbuffer = currentcontext.allocate(_backgroundgraphic, _backgroundgraph.clientrectangle);

// 雙緩衝graphic

_backgroundrendergraphic = _graphicsbuffer.graphics;

_backgroundrendergraphic.clear(color.white);

_backgroundrendergraphic.setclip(_backgroundgraph.clientrectangle);

// 記憶體bitmap

_backgroundmemorybitmap = new bitmap(_backgroundgraph.clientrectangle.width * 10, _backgroundgraph.clientrectangle.height, _backgroundrendergraphic);

// 記憶體graphic

_backgroundmemorygraphic = graphics.fromimage(_backgroundmemorybitmap);

_backgroundmemorygraphic.clear(color.white);

// 建立適用的繪圖區

_memorygraphichdc = createcompatibledc(_backgroundmemorygraphic.gethdc());

_memorybitmaphdc = _backgroundmemorybitmap.gethbitmap();

selectobject(_memorygraphichdc, _memorybitmaphdc);

// 描畫graphic

_backgrounddrawgraphic = graphics.fromhdc(_memorygraphichdc);

_backgrounddrawgraphic.smoothingmode = smoothingmode.highquality;

_backgrounddrawgraphic.textrenderinghint = textrenderinghint.cleartypegridfit;

_backgrounddrawgraphic.interpolationmode = interpolationmode.highqualitybilinear;

_backgrounddrawgraphic.pixeloffsetmode = pixeloffsetmode.highquality;}}

4.使用gdi+描畫曲線

public

void drawsomething()

5.使用bitblt向前臺描畫

public

void updateview()

C 實現雙緩衝

1 在記憶體中申請緩衝區,建立相容記憶體 2 建立位圖,並將點陣圖與緩衝區記憶體相關聯起來 3 在相容記憶體裡繪製 4 將繪製好的點陣圖拷貝到當前裝置 5 釋放相容記憶體。cpoint ptcenter crect rect,ellipserect getclientrect rect ptcent...

C 實現雙緩衝

首先宣告下,這篇資料也是整理別人的資料的基礎上,總結來的。在圖形影象處理過程中,雙緩衝技術是一種比較常見的技術。窗體在響應wm paint訊息時,需要對影象進行繪製處理。如果影象繪製次數過多,重繪過於頻繁時,或者當要繪製的物件太複雜,尤其是含有點陣圖時,一般計算機便力不從心了。顯示器上就會因為重新整...

mfc下實現雙緩衝的方法

本帖解決的問題 如何實現雙緩衝 為什麼實現了雙緩衝還是會閃爍?以下資料為本人積累和加上自己的經驗 1 簡介一下windows mfc的view顯示重新整理過程 1 使用背景刷填充view窗體 呼叫內在機制的 2 呼叫onpain ondraw 呼叫使用者的 2 產生閃爍的原因出在於 當我們很快地重新...