为什么渲染变成黑色

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);
        }        
    }        
}