我正在使用眼动仪来显示表格上的眼球运动。这些动作一直闪烁很多,所以我发现我可以使用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();
}
你可以在图像中看到圆圈出现在控件后面,看起来表格已经消失了吗?
答案 0 :(得分:1)
分配缓冲区时,它会使用您提供的图形创建兼容的渲染表面。但它不会复制它或其他任何东西,所以如果你只画一个圆圈,剩下的部分仍然是黑色的。
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
以使用Graphics
中的PaintEventArgs
:
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);
}
}
}