2016-08-16 101 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

所以我不能夠將填充存儲在列表中並將列表存儲在新列表中並清除第一個列表等等?能夠填補新的形狀? –