Рисование линий в PictureBox - PullRequest
1 голос
/ 05 июня 2011

Сначала мне нужно сделать несколько цветных каракулей (рисунок ниже взят из статьи М. Янга по раскрашиванию неподвижных изображений) для монохромного входного изображения, которое загружается в элемент управления PictureBox.

Enter image description here

Я пытаюсь использовать это, чтобы получить эффект:

private void PictureBoxOnMouseDown(Object sender, MouseEventArgs e)
{
    if((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        this.MouseInitialPosition = e.Location;
    }
}

private void PictureBoxOnMouseMove(Object sender, MouseEventArgs e)
{
    if((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        this.MouseLastPosition = e.Location;
    }
    this._PictureBox.Invalidate();
}

private void PictureBoxOnPaint(Object sender, PaintEventArgs e)
{
    using(var pen = new Pen(Color.Red, 3.0F))
    {
        e.Graphics.DrawLine(pen, this.MouseInitialPosition, this.MouseLastPosition);
    }
}

Но это дает мне не совсем то, чего я так долго ждала:

  • Я не могу поставить несколько строк. Строки не сохраняются;

  • Я перезаписываю строку строкой;

Во-вторых. Мне нужно получить все пиксели из изображения, на котором я рисую, и каким-то образом отфильтровать их (т.е. извлечь специальные). Как сохранить линии / каракули на изображении, а затем эффективно прочитать изображение?

Ответы [ 2 ]

2 голосов
/ 07 декабря 2012

Простым решением было бы сохранить строки, когда событие mouseMove происходит в элементе управления Picturebox, а затем сделать недействительной перерисовку:

public class Lines
{
    public Point startPoint = new Point();
    public Point endPoint = new Point();
}

Lines l = new Lines();
List<Lines> allLines = new List<Lines>();

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    // Collect endPoint when mouse moved
    if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        l.endPoint = e.Location;
        //Line completed
        allLines.Add(l);
        this.pictureBox1.Invalidate();
    }
}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    // Collect startPoint when left mouse clicked
    if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        l = new Lines();
        l.startPoint = e.Location;
    }
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    foreach (var aLine in allLines)
    {
        e.Graphics.DrawLine(Pens.Blue, aLine.startPoint, aLine.endPoint);
    }
}
1 голос
/ 06 июня 2011

Просто держите список строк. Затем, когда вызывается OnPaint, рисуем все линии.

Класс Line будет выглядеть примерно так:

public class Line
{
    public List<Point> Points = new List<Point>();

    public DrawLine(Pen pen, Grphics g)
    {
        for (int i = 0; i < Points.Count - 1; ++i)
            g.DrawLine(pen, Points[i], Points[i+1];
    }
}

private void PictureBoxOnMouseDown(Object sender, MouseEventArgs e)
{
    if((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        var newLine = new Line();
        newLine.Points.Add(e.Location);
        lines.Add(newLine);
    }
}

PictureBoxOnMouseMove(Object sender, MouseEventArgs e)
{
    if((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        lines[lines.Count-1].Points.Add(e.Location);
    }
}

private void PictureBoxOnPaint(Object sender, PaintEventArgs e)
{
    using(var pen = new Pen(Color.Red, 3.0F))
    {
        foreach (var line in lines)
            DrawLine(pen, e.Graphics)
    }
 }
...