在两个 windows 中同时在两个控件上绘制,毫不拖延
Drawing simultaneously on two controls in two windows without delay
在我的应用程序中,有 2 个 windows 并且都包含一个 PictureBox。第一个 (pb1) 允许交互,并且可以通过单击和鼠标移动事件更改图像。这些事件调用 pb1.Invalidate();效果很好。
我希望第二个 PictureBox (pb2) 也重绘,所以我从 pb1 的绘制事件中调用 pb2.Invalidate()。 [仅出于上下文考虑,第二个 PictureBox 显示几乎相同的图像,但比例更大,并且将来会遗漏绘图的某些部分,因此我在两个绘制事件中使用相同的方法来决定绘制什么和不绘制什么]
它可以工作,但它“滞后”,我希望它像第一个 PictureBox 上的油漆一样光滑。为了测试目的,我将绘画事件缩减为网格。
- 两个 windows 都是双缓冲的。
- 我尝试用 SkiaSharp 的 SKGLControls 替换图片框(应该有更好的性能)。示例代码仍然使用 SkiaEvents,因此如果两个控件都出现问题,请不要混淆。
- 我尝试使用 .Update() 或 .Refresh() 而不是 .Invalidate() 但我想它需要处理的东西太多了,应用程序崩溃了..
这是两个 OnPaint 事件调用的方法
public void Update(SKPaintGLSurfaceEventArgs e, bool bigscreen)
{
SKCanvas canvas = e.Surface.Canvas;
canvas.Clear(SKColors.Beige);
//Zoom to specified area
SKMatrix matrix = SKMatrix.Identity;
if (!bigscreen)
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(canvasSize / (float)zoomArea.Width, canvasSize / (float)zoomArea.Height));
}
else
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(bigCanvasSize / (float)zoomArea.Width, bigCanvasSize / (float)zoomArea.Height));
}
matrix = matrix.PreConcat(SKMatrix.CreateTranslation(-zoomArea.X, -zoomArea.Y));
canvas.SetMatrix(matrix);
DrawGrid(canvas);
}
和网格绘制方法
private void DrawGrid(SKCanvas canvas)
{
using (SKPaint paint = new SKPaint() { IsAntialias = true,Color=SKColors.LightGray,StrokeWidth = 1})
{
canvas.DrawLine(0, 0, 0, gridCanvas.Height, paint); //Size gridCanvas is always the same at the moment and defines the space where the grid is drawn
canvas.DrawLine(0, 0, gridCanvas.Width, 0, paint);
for (int i = 0; i <= (gridCanvas.Width - gridoffsetX) / pxPerSquare; i++)
{
canvas.DrawLine(i * pxPerSquare + gridoffsetX, 0, i * pxPerSquare + gridoffsetX, gridCanvas.Height, paint);
}
for (int i = 0; i <= (gridCanvas.Height - gridoffsetY) / pxPerSquare; i++)
{
canvas.DrawLine(0, i * pxPerSquare + gridoffsetY, gridCanvas.Width, i * pxPerSquare + gridoffsetY, paint);
}
}
}
最后是原始的 Paint Event
private void Pb1_PaintSurface(object sender, SKPaintGLSurfaceEventArgs e)
{
win2.UpdateDrawing(); //Just calls .Invalidate() on pb2
painter.Update(e, false);
}
examplePicture
所以我的问题是:有没有办法让两个控件几乎同时绘制而没有延迟,虽然我不明白为什么第一个 PictureBox 实时绘制而第二个不...
谢谢!
搜索 day 后,我在发布后立即找到了这个页面,这对我有帮助:
Onpaint events (invalidated) changing execution order after a period normal operation (runtime)
在我的应用程序中,有 2 个 windows 并且都包含一个 PictureBox。第一个 (pb1) 允许交互,并且可以通过单击和鼠标移动事件更改图像。这些事件调用 pb1.Invalidate();效果很好。
我希望第二个 PictureBox (pb2) 也重绘,所以我从 pb1 的绘制事件中调用 pb2.Invalidate()。 [仅出于上下文考虑,第二个 PictureBox 显示几乎相同的图像,但比例更大,并且将来会遗漏绘图的某些部分,因此我在两个绘制事件中使用相同的方法来决定绘制什么和不绘制什么]
它可以工作,但它“滞后”,我希望它像第一个 PictureBox 上的油漆一样光滑。为了测试目的,我将绘画事件缩减为网格。
- 两个 windows 都是双缓冲的。
- 我尝试用 SkiaSharp 的 SKGLControls 替换图片框(应该有更好的性能)。示例代码仍然使用 SkiaEvents,因此如果两个控件都出现问题,请不要混淆。
- 我尝试使用 .Update() 或 .Refresh() 而不是 .Invalidate() 但我想它需要处理的东西太多了,应用程序崩溃了..
这是两个 OnPaint 事件调用的方法
public void Update(SKPaintGLSurfaceEventArgs e, bool bigscreen)
{
SKCanvas canvas = e.Surface.Canvas;
canvas.Clear(SKColors.Beige);
//Zoom to specified area
SKMatrix matrix = SKMatrix.Identity;
if (!bigscreen)
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(canvasSize / (float)zoomArea.Width, canvasSize / (float)zoomArea.Height));
}
else
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(bigCanvasSize / (float)zoomArea.Width, bigCanvasSize / (float)zoomArea.Height));
}
matrix = matrix.PreConcat(SKMatrix.CreateTranslation(-zoomArea.X, -zoomArea.Y));
canvas.SetMatrix(matrix);
DrawGrid(canvas);
}
和网格绘制方法
private void DrawGrid(SKCanvas canvas)
{
using (SKPaint paint = new SKPaint() { IsAntialias = true,Color=SKColors.LightGray,StrokeWidth = 1})
{
canvas.DrawLine(0, 0, 0, gridCanvas.Height, paint); //Size gridCanvas is always the same at the moment and defines the space where the grid is drawn
canvas.DrawLine(0, 0, gridCanvas.Width, 0, paint);
for (int i = 0; i <= (gridCanvas.Width - gridoffsetX) / pxPerSquare; i++)
{
canvas.DrawLine(i * pxPerSquare + gridoffsetX, 0, i * pxPerSquare + gridoffsetX, gridCanvas.Height, paint);
}
for (int i = 0; i <= (gridCanvas.Height - gridoffsetY) / pxPerSquare; i++)
{
canvas.DrawLine(0, i * pxPerSquare + gridoffsetY, gridCanvas.Width, i * pxPerSquare + gridoffsetY, paint);
}
}
}
最后是原始的 Paint Event
private void Pb1_PaintSurface(object sender, SKPaintGLSurfaceEventArgs e)
{
win2.UpdateDrawing(); //Just calls .Invalidate() on pb2
painter.Update(e, false);
}
examplePicture
所以我的问题是:有没有办法让两个控件几乎同时绘制而没有延迟,虽然我不明白为什么第一个 PictureBox 实时绘制而第二个不... 谢谢!
搜索 day 后,我在发布后立即找到了这个页面,这对我有帮助: Onpaint events (invalidated) changing execution order after a period normal operation (runtime)