【发布时间】:2019-12-06 05:31:54
【问题描述】:
我正在开发一个ECG 项目,该项目实时显示心电图。我在图片框中绘制了我的图像。而我用来更新图像的方式是使用Forms.Timer调用Invalidate()来刷新和更新picturebox中的图像在picturebox_paint方法中,我创建了一个新的Bitmap并使用图形来绘制ECG的新线和网格每次。
所以,现在我的问题是我将计时器的间隔设置为 50 毫秒或 100 毫秒,但是有一个延迟,导致图像不会以我想要的速度更新。
我知道创建新位图会导致延迟,但我没有找到替换它的方法。我在想我可以在一开始就绘制整个心电图数据的位图,并在计时器滴答时将其向左移动,但我找不到一种方法来将位图移动到图片框中。
有人知道这个问题吗?
下面是我的paint方法的代码。
private void pictureBox1_paint(object sender, PaintEventArgs e){
// Draw the ECG.
DrawArea = new Bitmap(pictureBox1.Size.Width,pictureBox1.Size.Height);
using (g = Graphics.FromImage(DrawArea))
{
//dispose the original image.
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
// draw the labels
int numOfLabels = ((numOfCellsX - numOfCellsX % 4) / 4) * 2;
for (int l = 0; l < numOfLabels; l++)
{
g.DrawString((labelV).ToString(), drawFont, drawBrush, (unitOfLabel * l) + changeValueOfLabel, viewsizeY - 20);
labelV = labelV + unitOfLabel;
}
labelV -= numOfLabels * unitOfLabel;
// draw horizontal lines of gird
for (int y = 0; y <= numOfCellsY; ++y)
{
g.DrawLine(bgp, 0, y * cellSizeY, viewsizeX, y * cellSizeY);
}
// draw vertical lines of gri, +6 because here we are drawing 6 more lines on the right of the grid for further moving.
for (int x = 1; x <= numOfCellsX * 2; ++x)
{
g.DrawLine(bgp, (x * cellSizeX) + changeValue, 0, (x * cellSizeX) + changeValue, viewsizeY);
}
//drawPoints
g.DrawLines(mypen, points);
//draw the most top line
//g.DrawLine(bgp, viewsizeX - 1, 0, viewsizeX - 1, viewsizeY);
// draw the most right line
g.DrawLine(bgp, viewsizeX - 1, 0, viewsizeX - 1, viewsizeY);
//draw the most left line
g.DrawLine(bgp, 0, 0, 0, viewsizeY);
// draw the bottom line, the reason that draw those line outside the for loop, is because the location.X of
// the most left point of the picturebox is actually 599, therefore,it cannot display the 600 index point.
g.DrawLine(bgp, 0, viewsizeY - 1, viewsizeX, viewsizeY - 1);
// replace the image of the picturebox
pictureBox1.Image = DrawArea;
}
}
numberOfCellX 和 numberofLabel 小于 15,numberOfCellY 小于 8,并且我用秒表测试了仅用了 2ms 的绘制方法的运行时间。
我还测试了整个迭代的运行时间,包括更新图像和绘制它需要 27 毫秒。所以当我将 Timer 的间隔设置为 100 毫秒时。完成一个 Tick 大约需要 127 毫秒。
在不使用位图的情况下更新代码:
// Draw the ECG.
g = e.Graphics;
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
// draw the labels
int numOfLabels = ((numOfCellsX - numOfCellsX % 4) / 4) * 2;
for (int l = 0; l < numOfLabels; l++)
{
g.DrawString((labelV).ToString(), drawFont, drawBrush, (unitOfLabel * l) + changeValueOfLabel, viewsizeY - 20);
labelV = labelV + unitOfLabel;
}
labelV -= numOfLabels * unitOfLabel;
// draw horizontal lines of gird
for (int y = 0; y <= numOfCellsY; ++y)
{
g.DrawLine(bgp, 0, y * cellSizeY, viewsizeX, y * cellSizeY);
}
// draw vertical lines of gri, +6 because here we are drawing 6 more lines on the right of the grid for further moving.
for (int x = 1; x <= numOfCellsX * 2; ++x)
{
g.DrawLine(bgp, (x * cellSizeX) + changeValue, 0, (x * cellSizeX) + changeValue, viewsizeY);
}
//drawPoints
g.DrawLines(mypen, points);
//draw the most top line
//g.DrawLine(bgp, viewsizeX - 1, 0, viewsizeX - 1, viewsizeY);
// draw the most right line
g.DrawLine(bgp, viewsizeX - 1, 0, viewsizeX - 1, viewsizeY);
//draw the most left line
g.DrawLine(bgp, 0, 0, 0, viewsizeY);
// draw the bottom line, the reason that draw those line outside the for loop, is because the location.X of
// the most left point of the picturebox is actually 599, therefore,it cannot display the 600 index point.
g.DrawLine(bgp, 0, viewsizeY - 1, viewsizeX, viewsizeY - 1);
定时器代码: 更新grid和points的坐标,调用Invalidate刷新picturebox。
【问题讨论】:
-
嗨,欢迎来到堆栈溢出。请参阅How to Ask 链接以获取有关如何提出问题并相应更新您的问题的更多详细信息。例如,添加您制作的代码的最小版本。
-
直接在 PictureBox 表面上绘画(使用
PaintEventArgs'e.Graphics对象),这里不需要位图。您可以将绘图过程移动到一个独立的方法;将e.Graphics传递给此方法。如果/当您需要在 Bitmap 上修复绘图时,请传递从 Bitmap 派生的 Graphics 对象。顺便说一句,您的代码无法测试,缺少太多部分。 -
感谢您的建议,我把Bitmap的代码去掉,直接在PictureBox上画线。但是,延迟仍然存在。我只能达到 125 毫秒的时间间隔,最多每秒 8 帧,没有延迟。
-
您尚未使用您应用的修改更新问题中的代码,因此看不到问题(如果有的话)。如果您更新它或发布新问题来解决问题,了解
numOfLabels、numOfCellsY、numOfCellsX等的实际值会很有用。平均迭代次数非常重要。 -
对不起,我刚刚注意到了。现在更新了。