C#中的图形闪烁图形

2023-09-02 10:55:51 作者:吧唧一口可爱

我工作的一种绘图程序,但我有一个问题,闪烁,同时移动鼠标光标在绘制橡皮线。我希望你能帮助我删除线的闪烁,这里是code:

 使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data这;
使用System.Drawing中;
使用System.Linq的;
使用System.Text;
使用System.Windows.Forms的;

命名空间GraphicsTest
{
    公共部分类Form1中:形态
    {
        INT xFirst,yFirst;
        位图BM =新位图(1000,1000);
        图形BMG;
        显卡XG;
        喷喷=新钢笔(Color.Black,1);
        布尔画= FALSE;

        公共Form1中()
        {
            的InitializeComponent();
        }

        私人无效Form1_Load的(对象发件人,EventArgs的)
        {
            BMG = Graphics.FromImage(BM);
            XG = this.CreateGraphics();
            bmG.Clear(Color.White);
        }

        私人无效Form1_MouseDown(对象发件人,发送MouseEventArgs E)
        {
            xFirst = e.X;
            yFirst = e.Y;
            借鉴= TRUE;
        }

        私人无效Form1_MouseUp(对象发件人,发送MouseEventArgs E)
        {
            bmG.DrawLine(笔,xFirst,yFirst,e.X,e.Y);
            借鉴= FALSE;
            xG.DrawImage(BM,0,0);
        }

        私人无效Form1_MouseMove(对象发件人,发送MouseEventArgs E)
        {
            如果(画)
            {
                xG.DrawImage(BM,0,0);
                xG.DrawLine(笔,xFirst,yFirst,e.X,e.Y);
            }
        }

        私人无效Form1_Paint(对象发件人,PaintEventArgs的E)
        {
            xG.DrawImage(BM,0,0);
        }
    }
}
 

解决方案

先不使用的createGraphics(),除非你绝对必须的。一个事件处理程序的OnPaint 和呼叫的Invalidate()当你想刷新面。

绑定

如果你不希望它忽悠你需要双缓冲绘图表面。要做到这一点,最简单的方法是设置窗体的 DoubleBuffered 属性为True。

我会强烈建议,如果你打算扩展这个做你的图纸到PictureBox控件。图片框是双缓冲默认情况下,允许您控制您的绘图区域简单得多。

PPT中如何使自选图形连续闪烁

在code:

 公共部分类Form1中:形态
    {
    INT xFirst,yFirst;
    位图BM =新位图(1000,1000);
    图形BMG;
    喷喷=新钢笔(Color.Black,1);
    布尔画= FALSE;

    公共Form1中()
    {
        的InitializeComponent();
    }

    私人无效Form1_Load的(对象发件人,EventArgs的)
    {
        BMG = Graphics.FromImage(BM);
        bmG.Clear(Color.White);
    }

    私人无效Form1_MouseDown(对象发件人,发送MouseEventArgs E)
    {
        xFirst = e.X;
        yFirst = e.Y;
        借鉴= TRUE;
    }

    私人无效Form1_MouseUp(对象发件人,发送MouseEventArgs E)
    {
        bmG.DrawLine(笔,xFirst,yFirst,e.X,e.Y);
        借鉴= FALSE;
        无效();
    }

    私人无效Form1_MouseMove(对象发件人,发送MouseEventArgs E)
    {
        如果(画)
        {
            无效();
        }
    }

    私人无效Form1_Paint(对象发件人,PaintEventArgs的E)
    {
        如果(画){
            e.Graphics.DrawImage(BM,0,0);
            e.Graphics.DrawLine(笔,xFirst,yFirst,前,EY);
        } 其他 {
            e.Graphics.DrawImage(BM,0,0);
        }
    }
}
 

编辑:

另外一个问题,你正在创建一个私有成员。笔(和刷子,以及许多GDI对象)再present处理到需要处理,否则你的程序将泄漏非托管对象。无论是使用语句(在preferred和异常安全的方式)包装在或者在表单的处置方法。

另外在System.Drawing中,您可以访问一些pre-内置画笔和画刷不需要是(和不应该)处理。使用它们,如:

 私人无效Form1_Paint(对象发件人,PaintEventArgs的E)
    {
        如果(画){
            e.Graphics.DrawImage(BM,0,0);
            e.Graphics.DrawLine(Pens.Black,xFirst,yFirst,前,EY);
        } 其他 {
            e.Graphics.DrawImage(BM,0,0);
        }
    }
 

I am working on kind of drawing program but I have a problem with flickering while moving a mouse cursor while drawing a rubberband line. I hope you can help me to remove that flickering of line, here is the code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace GraphicsTest
{
    public partial class Form1 : Form
    {
        int xFirst, yFirst;
        Bitmap bm = new Bitmap(1000, 1000);
        Graphics bmG;
        Graphics xG;
        Pen pen = new Pen(Color.Black, 1);
        bool draw = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            bmG = Graphics.FromImage(bm);
            xG = this.CreateGraphics();
            bmG.Clear(Color.White);
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            xFirst = e.X;
            yFirst = e.Y;
            draw = true;
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            bmG.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
            draw = false;
            xG.DrawImage(bm, 0, 0);
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (draw)
            {
                xG.DrawImage(bm, 0, 0);
                xG.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
            }
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            xG.DrawImage(bm, 0, 0);
        }
    }
}

解决方案

First don't use CreateGraphics() unless you absolutely have to. Bind an event handler to OnPaint and call Invalidate() when you want to refresh the surface.

If you don't want it to flicker you'll need to double buffer your drawing surface. The easiest way to do this is to set your form's DoubleBuffered property to True.

I would highly recommend if you plan on extending this to do your drawing to the PictureBox control. PictureBox is double-buffered by default and allows you to control your drawing region much more simply.

In code:

public partial class Form1 : Form
    {
    int xFirst, yFirst;
    Bitmap bm = new Bitmap(1000, 1000);
    Graphics bmG;
    Pen pen = new Pen(Color.Black, 1);
    bool draw = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        bmG = Graphics.FromImage(bm);
        bmG.Clear(Color.White);
    }

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        xFirst = e.X;
        yFirst = e.Y;
        draw = true;
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        bmG.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
        draw = false;
        Invalidate();
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (draw)
        {
            Invalidate();
        }
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        if (draw) {
            e.Graphics.DrawImage(bm, 0, 0);
            e.Graphics.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
        } else {
            e.Graphics.DrawImage(bm, 0, 0);
        }
    }
}

Edit:

Another issue, you are creating a private Pen member. Pens (and Brushes, as well as many GDI+ objects) represent handles to unmanaged objects that need to be disposed otherwise your program will leak. Either wrap them in using statements (the preferred and exception-safe way) or explicitly dispose of them in the form's Dispose method.

Alternatively in System.Drawing you can access some pre-built Pens and Brushes that don't need to be (and shouldn't be) disposed. Use them like:

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        if (draw) {
            e.Graphics.DrawImage(bm, 0, 0);
            e.Graphics.DrawLine(Pens.Black, xFirst, yFirst, e.X, e.Y);
        } else {
            e.Graphics.DrawImage(bm, 0, 0);
        }
    }