简体   繁体   English

在Winforms C#上的MS Paint等表格上绘制连续的线

[英]Drawing a consecutive line on a form like MS paint on Winforms C#

I got a question about the Graphics object. 我有一个关于Graphics对象的问题。 I want to draw an consecutive line like MS paint. 我想画一条连续的线,例如MS paint。 I don't know how to implement such thing. 我不知道该怎么实现。 I do know how to start a line from the mouse location. 我确实知道如何从鼠标位置开始一行。 This I do on a picturebox and add the new Point(eX, eY). 我在图片框上执行此操作,然后添加新的Point(eX,eY)。 The otherline could not be the same ofcourse else there would be no line visible. 另一行不能与路线相同,否则将看不到任何行。 I could not make the other Point(10, 10) or something like that. 我无法制作另一个Point(10,10)或类似的东西。 Because then it would create a line always from the same point. 因为那样的话,它将总是从同一点创建一条线。

Does anyone know how to draw consecutive lines(with curves) 有谁知道如何绘制连续的线(带曲线)

Does it has something to do with the mouse_down and mouse_up event? 它与mouse_down和mouse_up事件有关吗? I am really stuck with this problem for a long time. 我确实长期困扰这个问题。 If anyone of you have the time to explain me method that would work, that would be great! 如果你们中有人有时间向我解释可行的方法,那就太好了!

Thanks in advance! 提前致谢!

I just implemented simple paint for you. 我刚刚为您实现了简单的绘画。 Just create a new project and copy this code below to Form1.cs file. 只需创建一个新项目并将下面的代码复制到Form1.cs文件即可。 Comments in code should explain how it works. 代码中的注释应说明其工作原理。

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

Result: 结果:
在此处输入图片说明

Broadly: 宽广地:

  1. On MouseDown , capture the mouse and store the current location. MouseDown ,捕获鼠标并存储当前位置。 This location is your initial Point value. 该位置是您的初始Point值。
  2. On MouseMove , add the current location to your list of points. MouseMove ,将当前位置添加MouseMove列表中。
  3. On MouseUp , complete your curve as appropriate, stop capturing the mouse. MouseUp ,根据需要完成曲线,停止捕获鼠标。

When rendering, convert your list of Point values to an array and pass it to the Graphics.DrawLines() method. 渲染时,将Point值列表转换为数组,然后将其传递给Graphics.DrawLines()方法。 As a possible optimization, once the user is done drawing, permanently convert the list to an array. 作为一种可能的优化,一旦用户完成绘制,就将列表永久转换为数组。 Alternatively, use a Bitmap instance as your rendering cache. 或者,使用Bitmap实例作为渲染缓存。

Note that you can configure the Pen object used to draw the lines to apply special effects, like end caps and mitered joints. 请注意,您可以配置用于绘制线条的Pen对象以应用特殊效果,例如端盖和斜接。

To draw curves, use the Graphics.DrawBeziers() method instead. 要绘制曲线,请改用Graphics.DrawBeziers()方法。 Note that in this case, the points captured during the mouse events should be every third point in the array passed to the method. 请注意,在这种情况下,鼠标事件期间捕获的点应该是传递给该方法的数组中的每三个点。 The two points between each of those points are the control points for each curve. 这些点之间的两个点是每个曲线的控制点

You should probably start with DrawLines() , as it's much simpler. 您可能应该从DrawLines()开始,因为它要简单得多。 Once you have that working nicely, then you can complicate your life with the DrawBeziers() method. 一旦运行良好,就可以使用DrawBeziers()方法使生活复杂化。 At a minimum, you will have to automatically compute default control points for use with the method. 至少,您将必须自动计算用于该方法的默认控制点。 Preferably, you will give the user a way to edit the control points, so that they can customize the curve. 优选地,您将为用户提供一种编辑控制点的方法,以便他们可以自定义曲线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM