【问题标题】:Drawing a consecutive line on a form like MS paint on Winforms C#在 Winforms C# 上的 MS 绘图等窗体上绘制连续线
【发布时间】:2015-02-21 19:54:11
【问题描述】:

我有一个关于 Graphics 对象的问题。我想像 MS paint 一样画一条连续的线。我不知道如何实现这样的事情。我确实知道如何从鼠标位置开始一行。我在图片框上执行此操作并添加新点(e.X,e.Y)。另一条线当然不能相同,否则将看不到一条线。我无法制作另一个 Point(10, 10) 或类似的东西。因为那样它会始终从同一点创建一条线。

有谁知道如何画连续的线(带曲线)

和 mouse_down 和 mouse_up 事件有关系吗?我真的被这个问题困扰了很长时间。如果你们中的任何人有时间向我解释可行的方法,那就太好了!

提前致谢!

【问题讨论】:

    标签: c# winforms graphics lines


    【解决方案1】:

    我刚刚为你实现了简单的绘制。只需创建一个新项目并将下面的代码复制到 Form1.cs 文件中。代码中的注释应该解释它是如何工作的。

    public partial class Form1 : Form
    {
        private Bitmap bmp; // Place to store our drawings
        private List<Point> points; // Points of currently drawing line
        private Pen pen; // Pen we will use to draw
    
        public Form1()
        {
            InitializeComponent();
            DoubleBuffered = true; // To avoid flickering effect
    
            bmp = new Bitmap(640, 480); // This is our canvas that will store drawn lines
            using (Graphics g = Graphics.FromImage(bmp))
                g.Clear(Color.White); // Let's make it white, like paper
    
            points = new List<Point>(); // Here we will remember the whole path
            pen = new Pen(Color.Black);
    
            MouseDown += OnMouseDown; // Start drawing
            MouseMove += OnMouseMove; // Drawing...
            MouseUp += OnMouseUp; // Stop drawing
            Paint += OnPaint; // Show the drawing
        }
    
        void OnPaint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(bmp, 0, 0); // Show what is drawn
            if (points.Count > 0)
                e.Graphics.DrawLines(pen, points.ToArray()); // Show what is currently being drawn
        }
    
        void OnMouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
    
            points.Clear();
            points.Add(e.Location); // Remember the first point
        }
    
        void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
    
            points.Add(e.Location); // Add points to path
            Invalidate(); // Force to repaint
        }
    
        void OnMouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
    
            SaveToBitmap(); // Save the drawn line to bitmap
            points.Clear(); // Our drawing is saved, we can clear the list of points
        }
    
        private void SaveToBitmap()
        {
            if (points.Count == 0)
                return;
    
            using (Graphics g = Graphics.FromImage(bmp))
                g.DrawLines(pen, points.ToArray()); // Just draw current line on bitmap
        }
    }
    

    结果:

    【讨论】:

    • 正是我需要的。非常感谢!
    • @MaximedeLange “很多” 2 个字
    • 只是一个小的修正:在方法 SaveToBitmap()points.Count 为 1 时,你会得到一个异常(当只有一个点时不能在两点之间划一条线点)所以做 if 语句if(points.Count &lt; 2)
    • 您可以通过在 btnClean 方法上使用它来实现一个 Clean 按钮:bmp = new Bitmap(640, 480)
    【解决方案2】:

    广义上:

    1. MouseDown 上,捕获鼠标并存储当前位置。此位置是您的初始 Point 值。
    2. MouseMove 上,将当前位置添加到您的点列表中。
    3. MouseUp 上,根据需要完成曲线,停止捕捉鼠标。

    渲染时,将Point 值列表转换为数组并将其传递给Graphics.DrawLines() 方法。作为一种可能的优化,一旦用户完成绘图,将列表永久转换为数组。或者,使用 Bitmap 实例作为渲染缓存。

    请注意,您可以配置用于绘制线条的 Pen 对象以应用特殊效果,例如端盖和斜接接头。

    要绘制曲线,请改用Graphics.DrawBeziers() 方法。请注意,在这种情况下,鼠标事件期间捕获的点应该是传递给该方法的数组中的每三个点。这些点之间的两点是每条曲线的控制点

    您可能应该从DrawLines() 开始,因为它更简单。一旦你让它工作得很好,那么你可以使用DrawBeziers() 方法使你的生活复杂化。至少,您必须自动计算用于该方法的默认控制点。最好为用户提供一种编辑控制点的方法,以便他们可以自定义曲线。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多