为什么渲染变成黑色
why is rendering turning form black
我正在使用眼动仪在表格上显示眼球运动。运动一直在闪烁,所以我发现我可以使用 BufferedGraphics,它一切正常,除了当眼睛运动开始时它会将表格从原始颜色变为黑色。这是代码。希望有人能帮忙!
private void button2_Click(object sender, EventArgs e)
{
var host = new Host();
var gazeStream = host.Streams.CreateGazePointDataStream();
gazeStream.GazePoint((x, y, ts)
=> drawCircle(new PointF((float)x, (float)y)));
}
delegate void SetCallback(PointF point);
private void drawCircle(PointF point)
{
float x = point.X;
float y = point.Y;
if (this.InvokeRequired)
{
SetCallback d = new SetCallback(drawCircle);
this.Invoke(d, new object[] { point });
}
else
{
SolidBrush semiTransBrush = new SolidBrush(Color.Coral);
Pen pen = new Pen(Color.Aquamarine, 2);
BufferedGraphicsContext currentContext;
BufferedGraphics myBuffer;
// Gets a reference to the current BufferedGraphicsContext
currentContext = BufferedGraphicsManager.Current;
// Creates a BufferedGraphics instance associated with Form1, and with
// dimensions the same size as the drawing surface of Form1.
myBuffer = currentContext.Allocate(this.CreateGraphics(),this.DisplayRectangle);
myBuffer.Graphics.DrawEllipse(pen, x, y, 100, 100);
myBuffer.Graphics.FillEllipse(semiTransBrush, x, y, 100, 100);
// Renders the contents of the buffer to the specified drawing surface.
myBuffer.Render(this.CreateGraphics());
myBuffer.Dispose();
}
您可以在图像中看到圆圈出现在控件后面,看起来表格已经消失了?
当您分配缓冲区时,它会创建一个与您提供的图形兼容的渲染表面。但它不会复制它或任何东西,所以如果你只画一个圆圈,其余部分将保持黑色。
BufferedGraphics
确实可以帮助您在特殊情况下避免闪烁(例如,由于某些原因必须禁用系统双缓冲时),但这里这是一个矫枉过正的问题。
所以关键是启用双缓冲并在 Paint
事件(或 OnPaint
方法)中进行每次绘制。在您的代码中,您会立即绘制,它总是闪烁。相反,您应该只使表单无效并让系统执行常规重绘会话,如果您愿意,可以使用双缓冲。
进入构造函数:
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
然后修改点击事件:
private PointF lastGazePoint;
private void button2_Click(object sender, EventArgs e)
{
var host = new Host();
var gazeStream = host.Streams.CreateGazePointDataStream();
gazeStream.GazePoint((x, y, ts) =>
{
lastGazePoint = new PointF((float)x, (float)y);
Invalidate();
});
}
这幅画本身:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
DrawCircle(e.Graphics, lastGazePoint.X, lastGazePoint.Y);
}
最后,修改 DrawCircle
以使用 PaintEventArgs
中的 Graphics
:
private void DrawCircle(Graphics g, float x, float y)
{
using (Brush semiTransBrush = new SolidBrush(Color.Coral))
{
using (Pen pen = new Pen(Color.Aquamarine, 2))
{
g.DrawEllipse(pen, x, y, 100, 100);
g.FillEllipse(semiTransBrush, x, y, 100, 100);
}
}
}
我正在使用眼动仪在表格上显示眼球运动。运动一直在闪烁,所以我发现我可以使用 BufferedGraphics,它一切正常,除了当眼睛运动开始时它会将表格从原始颜色变为黑色。这是代码。希望有人能帮忙!
private void button2_Click(object sender, EventArgs e)
{
var host = new Host();
var gazeStream = host.Streams.CreateGazePointDataStream();
gazeStream.GazePoint((x, y, ts)
=> drawCircle(new PointF((float)x, (float)y)));
}
delegate void SetCallback(PointF point);
private void drawCircle(PointF point)
{
float x = point.X;
float y = point.Y;
if (this.InvokeRequired)
{
SetCallback d = new SetCallback(drawCircle);
this.Invoke(d, new object[] { point });
}
else
{
SolidBrush semiTransBrush = new SolidBrush(Color.Coral);
Pen pen = new Pen(Color.Aquamarine, 2);
BufferedGraphicsContext currentContext;
BufferedGraphics myBuffer;
// Gets a reference to the current BufferedGraphicsContext
currentContext = BufferedGraphicsManager.Current;
// Creates a BufferedGraphics instance associated with Form1, and with
// dimensions the same size as the drawing surface of Form1.
myBuffer = currentContext.Allocate(this.CreateGraphics(),this.DisplayRectangle);
myBuffer.Graphics.DrawEllipse(pen, x, y, 100, 100);
myBuffer.Graphics.FillEllipse(semiTransBrush, x, y, 100, 100);
// Renders the contents of the buffer to the specified drawing surface.
myBuffer.Render(this.CreateGraphics());
myBuffer.Dispose();
}
您可以在图像中看到圆圈出现在控件后面,看起来表格已经消失了?
当您分配缓冲区时,它会创建一个与您提供的图形兼容的渲染表面。但它不会复制它或任何东西,所以如果你只画一个圆圈,其余部分将保持黑色。
BufferedGraphics
确实可以帮助您在特殊情况下避免闪烁(例如,由于某些原因必须禁用系统双缓冲时),但这里这是一个矫枉过正的问题。
所以关键是启用双缓冲并在 Paint
事件(或 OnPaint
方法)中进行每次绘制。在您的代码中,您会立即绘制,它总是闪烁。相反,您应该只使表单无效并让系统执行常规重绘会话,如果您愿意,可以使用双缓冲。
进入构造函数:
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
然后修改点击事件:
private PointF lastGazePoint;
private void button2_Click(object sender, EventArgs e)
{
var host = new Host();
var gazeStream = host.Streams.CreateGazePointDataStream();
gazeStream.GazePoint((x, y, ts) =>
{
lastGazePoint = new PointF((float)x, (float)y);
Invalidate();
});
}
这幅画本身:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
DrawCircle(e.Graphics, lastGazePoint.X, lastGazePoint.Y);
}
最后,修改 DrawCircle
以使用 PaintEventArgs
中的 Graphics
:
private void DrawCircle(Graphics g, float x, float y)
{
using (Brush semiTransBrush = new SolidBrush(Color.Coral))
{
using (Pen pen = new Pen(Color.Aquamarine, 2))
{
g.DrawEllipse(pen, x, y, 100, 100);
g.FillEllipse(semiTransBrush, x, y, 100, 100);
}
}
}