做了一個類似示波器功能的上位機界面,通過串口接收下位機傳來的資料。
采用的是串口事件每接收128個資料,繪制一次圖形(在畫布范圍內繪制),但下位機每隔十幾毫秒上傳一組128個資料,也就是每隔十幾毫秒,上位機都要重繪一次,我是使用委托
這是繪圖函式里的,繪制完后釋放資源,進入委托,也就是繪圖完成后一起顯示
private void m_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
。。。。。。。。
draw();
}
private void draw()
{
。。。。。。。。
g.Dispose();
showdelegate show = new showdelegate(showpicture);
this.Invoke(show);
}
private void showpicture()
{
pictureBox1.Visible = false;
pictureBox1.Visible = true;
}
現在波形顯示沒問題,就是閃爍比較嚴重,請問有什么好的解決辦法嗎?
uj5u.com熱心網友回復:
渲染機制的問題。我建議你將每次要顯示的波形和坐標在后臺繪制成一個bitmap,然后一次在界面上顯示這張bitmap,而不是每次每個點都在界面上通過GDI畫出來,因為你每畫一個點可能就會引發一次渲染。uj5u.com熱心網友回復:
Form 增加以下代碼試試protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
uj5u.com熱心網友回復:
這個我也試過了,在draw函式里面添加
private void draw(n個資料點)
{
Bitmap bmp1 = new Bitmap(580, 430);
Graphics g = Graphics.FromImage(bmp1);
g.Clear(Color.White);
。。。。。。。。
一次將n個資料繪制波形。。。。 //但這樣還是有閃爍,n越大,閃爍越嚴重
。。。。。
pictureBox1.Image = bmp1; //然后再顯示
g.Dispose();
}
uj5u.com熱心網友回復:
好像并沒有緩解,我是像函式一樣直接添加到form這個類里面的uj5u.com熱心網友回復:
畫面內容在變化,感覺有閃爍是正常的你需要適當降低重繪頻率,并做插值處理
當每次重繪前后的畫面變化不大的時候,自然就沒有閃爍感了
uj5u.com熱心網友回復:
pictureBox1.Visible = false;pictureBox1.Visible = true;
這是啥代碼?
uj5u.com熱心網友回復:
什么叫“繪圖完成后一起顯示”?難道你不是繪128個資料之后一起顯示的么?如果要在多個UI執行緒處理周期程序中“暫停界面渲染”,在.net有標準的函式。而且你打開每一個表單的 designer.cs 檔案在第一行和最有一行都會看到人家是怎樣“一起重繪整個form上的控制元件然后才顯示”的。不是你那種奇怪的想法。
uj5u.com熱心網友回復:
是每接收128個資料進入一次繪圖函式draw(),但draw函式并不只是將這128個點連線,因為是類似示波器功能,資料量是不斷更新,第一次是128個數,第二次是256,第三次384......但一次繪制的點不會超過500個點,再加上有調節時基的功能,時基越大,一次繪制的點就越多。上面那個代碼作用類似于新建位圖,在位圖上繪制完成后再賦值給picturebox.image,但還是會有閃爍。
uj5u.com熱心網友回復:
重繪頻率確實有點高,調低是會好一點了。但為了真實反映電壓的變化,不得不讓他實時顯示了,畢竟串口緩沖區大小有限,擔心資料會堆積等其他問題。至于差值處理,譬如一個正弦波,雖然有規律,但時間推移,波形左移的話,每個點的資料都會發生變化,好像還不太好做差值處理,請問你說的差值處理是這個意思嗎?uj5u.com熱心網友回復:
設備傳來的資料保存在一個佇列里,顯示所用資料也是從佇列中取的降低重繪頻率是指隔幾個取一個(即抽樣顯示)
如需要有預警信號之類的,則在資料入隊時產生
插值處理是指平滑劇烈的變化
其實畫面中并不需要保存太多的歷史資料,多了反而會影響實時資料的展示
uj5u.com熱心網友回復:
明白了,太感謝了!uj5u.com熱心網友回復:
謝謝大佬uj5u.com熱心網友回復:
示波器很多年前做過,使用TeeChart控制元件,限定重繪周期,用佇列控制總的繪圖點數,超過比如500 就把前面的點丟棄uj5u.com熱心網友回復:
不要直接在畫布上畫,用雙快取。先生成bitmap,在bitmap上畫,畫好后,顯示上去。uj5u.com熱心網友回復:
使用 GDI 機制繪圖,閃爍是必然的,只是嚴重程度不同而已。上面的方法只能緩解而不能根除,這是 GDI 機制的問題。研究一下 DirectDraw 吧。uj5u.com熱心網友回復:
winform自帶雙緩沖轉載請註明出處,本文鏈接:https://www.uj5u.com/net/94769.html
標籤:C#
