2011-06-05 144 views
1

首先,我需要在加载到PictureBox控件的单色输入图像上制作一些颜色涂鸦(下面的图片来自M. Yang关于静止图像着色的文章)。在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

简单的解决办法是,当一个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

只需保留一行行。然后,当调用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) 
    } 
} 
+0

在拖动,你会产生很多鼠标移动事件。在此代码中,所有这些事件都会导致添加一行。经过一次拖拽后,您将在线条集合中获得很多线条,而每条线条需要一条线条。执行此操作的正确方法是在每次移动鼠标后添加该行,但在drag = mouse up事件结束时添加该行。 – 2015-12-30 13:04:16

+1

@HaraldDutch,OP询问有关涂鸦而不是线条。 – 2015-12-30 20:53:58