2016-08-16 109 views
0

(新增功能和玩弄一个基本的涂料应用程序)我发现了详细的代码填充填充的指令,但因为我是新的,它很难理解它的每一个部分,而不是复制,我想尝试做我自己的简单(小规模)洪水填充。将鼠标输入的填充路径用作填充路径之间的填充?

是否可以使用填充路径作为填充?我会绘制路径并使用鼠标在屏幕上确定我的x,y,并让图形路径找出它是否具有边框(从绘制的路径指向的点),如果是,请用这些颜色填充这些路径?

这是什么想法,但显然它不工作,所以我会如何去做这个工作?

namespace WindowsFormsApplication3 
{ 
public partial class Form1 : Form 
{ 
    Graphics g; 
    readonly Pen pen = new Pen(Color.Navy, 2); 
    Point oldCoords; 
    GraphicsPath graphicsPaths = new GraphicsPath(); 
    bool spaceFound = false; 


    public Form1() 
    { 
     InitializeComponent(); 
     g = panel1.CreateGraphics(); 
    } 

    private void panel1_MouseDown(object sender, MouseEventArgs e) 
    { 
     Point mousePt = new Point(e.X, e.Y); 

     if (e.Button == MouseButtons.Right &&    
       graphicsPaths.IsVisible(mousePt)) 
     { 
      spaceFound = true; 
     } 
    } 

    private void panel1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      if (oldCoords.IsEmpty) 
       graphicsPaths.StartFigure(); 
      else 
      { 
       graphicsPaths.AddLine(oldCoords, new Point(e.X, e.Y)); 
       g.DrawPath(pen, graphicsPaths); 
      } 
      oldCoords = new Point(e.X, e.Y); 
     } 
     else 
      oldCoords = Point.Empty; 
    } 

    private void panel1_MouseUp(object sender, MouseEventArgs e) 
    { 

    } 

    private void panel1_Paint(object sender, PaintEventArgs e) 
    { 
     g.DrawPath(pen, graphicsPaths); 

     if(spaceFound == true) 
     { 
      g.FillPath(Brushes.AliceBlue, graphicsPaths); 
     } 
    } 
    } 

}

回答

1

是的,这是完全可能的;当然,你会想在List<GraphicsPath>路径存储在MouseUp活动,让更多的填充形状..

您需要修改代码中的几个问题:

  • path.FillModeWinding
  • 决不缓存Graphics object
  • 决不使用control.CreateGraphics()
  • 不缓存PensBrushes
  • 只画在Paint事件,除非你做想图纸到坚持

最后一点威力实际应用在这里:也许你不要想让当前的绘制轮廓保持可见?那么,只有这种情况下,你可以坚持绘制它在MouseMoveGraphics对象在飞行中创建。

enter image description here

这里是一个修正版本:

Point oldCoords; 
GraphicsPath graphicsPaths = new GraphicsPath() { FillMode = FillMode.Winding }; 
bool spaceFound = false; 

private void drawPanel1_MouseDown(object sender, MouseEventArgs e) 
{ 
    if (e.Button == MouseButtons.Right && graphicsPaths.IsVisible(e.Location)) 
    { 
     spaceFound = true; 
     drawPanel1.Invalidate(); 
    } 
} 

private void drawPanel1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (e.Button == MouseButtons.Left) 
    { 
     if (oldCoords.IsEmpty) graphicsPaths.StartFigure(); 
     else 
     { 
      graphicsPaths.AddLine(oldCoords, new Point(e.X, e.Y)); 
      drawPanel1.Invalidate(); 
     } 
     oldCoords = new Point(e.X, e.Y); 
    } 
    else oldCoords = Point.Empty; 
} 

private void drawPanel1_Paint(object sender, PaintEventArgs e) 
{ 
    using (Pen pen = new Pen(Color.Black, 2f)) 
     e.Graphics.DrawPath(pen, graphicsPaths); 

    if (spaceFound == true) 
    { 
     e.Graphics.FillPath(Brushes.AliceBlue, graphicsPaths); 
    } 
} 

注意,这将填补你的路径,但不是真正的floodfill的方式,即它总是会补全路径,而不仅仅是你点击的最内层的部分。对于真正的填充,需要更多涉及的代码实际上遍及从点击位置开始的所有相邻像素。

一个真正的洪水的例子是herehere

+0

哇这很酷,你似乎知道很多,谢谢。我会试图找出列表中存储的路径,所以我可以有不同颜色填充的多个形状。你昨天展示了我的一个很好的例子,看看我是否将它结合在这里。 –

+0

请注意,它会填补你的路径,但不是真正的填充方式,即它将始终填充整个路径,而不仅仅是你点击的最内层的段。对于真正的填充,需要更多涉及的代码实际上遍及从点击位置开始的所有相邻像素。 – TaW

+0

所以我不能够将填充存储在列表中并将列表存储在新列表中并清除第一个列表等等?能够填补新的形状? –