Skip to content
This repository was archived by the owner on Sep 21, 2023. It is now read-only.

Commit b1350e9

Browse files
committed
Add Flood Fill capability
1 parent b8936ca commit b1350e9

File tree

7 files changed

+156
-6
lines changed

7 files changed

+156
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Drawing;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace winforms_image_processor
9+
{
10+
[Serializable]
11+
class Fill : Shape
12+
{
13+
public Point seedPoint;
14+
15+
public Fill(Color col, Point p) : base(col)
16+
{
17+
shapeType = DrawingShape.FILL;
18+
seedPoint = p;
19+
}
20+
21+
public override int AddPoint(Point point)
22+
{
23+
throw new NotImplementedException();
24+
}
25+
26+
public override List<ColorPoint> GetPixels(params object[] param)
27+
{
28+
throw new NotImplementedException();
29+
}
30+
31+
public override List<ColorPoint> GetPixelsAA(Bitmap bmp)
32+
{
33+
throw new NotImplementedException();
34+
}
35+
36+
public override string howToDraw()
37+
{
38+
throw new NotImplementedException();
39+
}
40+
41+
public override void MovePoints(Point displacement)
42+
{
43+
seedPoint += (Size)displacement;
44+
}
45+
46+
public override string ToString()
47+
{
48+
return "Filled region";
49+
}
50+
}
51+
}

winforms-image-processor/winforms-image-processor/DrawTools/Filler.cs

+52-1
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,56 @@ ColorPoint AddPoint(Point point)
161161

162162
return new ColorPoint(fillImage.GetPixelFast(point.X % fillImage.Width, point.Y % fillImage.Height), point);
163163
}
164+
165+
166+
}
167+
168+
public struct FillLog
169+
{
170+
public Color seedCol;
171+
public Point seedPoint;
172+
173+
public FillLog(Color col, Point p)
174+
{
175+
seedCol = col;
176+
seedPoint = p;
177+
}
178+
}
179+
180+
public static class FloodFiller
181+
{
182+
public static Bitmap FourWayFloodFill(Bitmap bmp, Color COLOR, Point q)
183+
// https://stackoverflow.com/questions/1257117/a-working-non-recursive-floodfill-algorithm-written-in-c/1257195
184+
{
185+
int h = bmp.Height;
186+
int w = bmp.Width;
187+
188+
if (q.Y < 0 || q.Y > h - 1 || q.X < 0 || q.X > w - 1)
189+
return bmp;
190+
191+
Color SEED_COLOR = bmp.GetPixelFast(q.X, q.Y);
192+
193+
Stack<Point> stack = new Stack<Point>();
194+
stack.Push(q);
195+
while (stack.Count > 0)
196+
{
197+
Point p = stack.Pop();
198+
int x = p.X;
199+
int y = p.Y;
200+
if (y < 0 || y > h - 1 || x < 0 || x > w - 1)
201+
continue;
202+
Color val = bmp.GetPixelFast(x, y);
203+
if (val == SEED_COLOR)
204+
{
205+
bmp.SetPixelFast(x, y, COLOR);
206+
stack.Push(new Point(x + 1, y));
207+
stack.Push(new Point(x - 1, y));
208+
stack.Push(new Point(x, y + 1));
209+
stack.Push(new Point(x, y - 1));
210+
}
211+
}
212+
return bmp;
213+
}
214+
164215
}
165-
}
216+
}

winforms-image-processor/winforms-image-processor/Forms/DrawForm.Designer.cs

+13-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

winforms-image-processor/winforms-image-processor/Forms/DrawForm.cs

+33-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace winforms_image_processor
1313
{
14-
public enum DrawingShape { EMPTY, LINE, CIRCLE, POLY, CAPS, RECT, CPOLY };
14+
public enum DrawingShape { EMPTY, LINE, CIRCLE, POLY, CAPS, RECT, CPOLY, FILL };
1515

1616
public partial class DrawForm : Form
1717
{
@@ -72,15 +72,20 @@ void RefreshShapes()
7272
{
7373
Bitmap bmp = NewBitmap();
7474
foreach (var shape in shapes)
75-
DrawShape(bmp, shape);
75+
{
76+
if (shape.shapeType == DrawingShape.FILL)
77+
bmp = FloodFiller.FourWayFloodFill(bmp, shape.shapeColor, ((Fill)shape).seedPoint);
78+
else
79+
DrawShape(bmp, shape);
80+
}
7681

7782
pictureBox1.Image = bmp;
7883
}
7984

8085
Bitmap DrawShape(Bitmap bmp, Shape shape)
8186
{
8287
if (!antialiasingToolStripMenuItem.Checked || !shape.supportsAA)
83-
foreach (var point in shape.GetPixels(showClipBorderToolStripMenuItem.Checked, colorDialog2.Color))
88+
foreach (var point in shape.GetPixels(showClipBorderToolStripMenuItem.Checked, colorDialog2.Color, bmp))
8489
{
8590
if (point.Point.X >= pictureBox1.Width || point.Point.Y >= pictureBox1.Height || point.Point.X <= 0 || point.Point.Y <= 0)
8691
continue;
@@ -103,6 +108,9 @@ Bitmap DrawShape(Bitmap bmp, Shape shape)
103108

104109
Shape currentShape = null;
105110
DrawingShape currentDrawingShape = DrawingShape.EMPTY;
111+
112+
bool canRefresh = true;
113+
106114
bool drawing = false;
107115
bool moving = false;
108116
bool clipping = false;
@@ -160,6 +168,13 @@ private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
160168
if (1 == currentShape.AddPoint(e.Location))
161169
clipMode(false, null);
162170
}
171+
172+
if (flooding)
173+
{
174+
shapes.Add(new Fill(colorDialog1.Color, e.Location));
175+
flooding = false;
176+
RefreshShapes();
177+
}
163178
}
164179

165180
private void midpointCircleToolStripMenuItem_Click(object sender, EventArgs e)
@@ -187,6 +202,13 @@ private void rectangleToolStripMenuItem_Click(object sender, EventArgs e)
187202
drawMode(true, new Rectangle(colorDialog1.Color, (int)numericUpDown1.Value));
188203
}
189204

205+
bool flooding = false;
206+
207+
private void floodFillToolStripMenuItem1_Click(object sender, EventArgs e)
208+
{
209+
flooding = true;
210+
}
211+
190212
void clipMode(bool status, Shape shape, int modify_index = -1)
191213
{
192214
if (!status && shapes[index].shapeType == DrawingShape.POLY)
@@ -395,7 +417,7 @@ private void showClipBorderToolStripMenuItem_Click(object sender, EventArgs e)
395417
}
396418

397419
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
398-
{
420+
{
399421
if (shapes.Count < 1)
400422
{
401423
button4.Enabled = false;
@@ -413,5 +435,12 @@ private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
413435
button4.Enabled = (((Shape)listBox1.SelectedItem).shapeType == DrawingShape.POLY || ((Shape)listBox1.SelectedItem).shapeType == DrawingShape.CPOLY) ? true : false;
414436
button5.Enabled = (((Shape)listBox1.SelectedItem).shapeType == DrawingShape.POLY || ((Shape)listBox1.SelectedItem).shapeType == DrawingShape.CPOLY) ? true : false;
415437
}
438+
439+
private void selectColorToolStripMenuItem_Click(object sender, EventArgs e)
440+
{
441+
colorDialog3.ShowDialog();
442+
}
443+
444+
416445
}
417446
}

winforms-image-processor/winforms-image-processor/Forms/DrawForm.resx

+3
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,7 @@
126126
<metadata name="colorDialog2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
127127
<value>253, 17</value>
128128
</metadata>
129+
<metadata name="colorDialog3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
130+
<value>374, 17</value>
131+
</metadata>
129132
</root>

winforms-image-processor/winforms-image-processor/SaveTools/ShapeSerializer.cs

+3
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ public static void Save<T>(string filename, BindingList<T> data) where T : class
6363
case DrawingShape.RECT:
6464
formatter.Serialize(stream, (Rectangle)shaped);
6565
break;
66+
case DrawingShape.FILL:
67+
formatter.Serialize(stream, (Fill)shaped);
68+
break;
6669
}
6770
}
6871
}

winforms-image-processor/winforms-image-processor/winforms-image-processor.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<Compile Include="CacheManager\CacheManager.cs" />
5353
<Compile Include="DrawTools\Clipping.cs" />
5454
<Compile Include="DrawTools\ClippedPolygon.cs" />
55+
<Compile Include="DrawTools\Fill.cs" />
5556
<Compile Include="DrawTools\Filler.cs" />
5657
<Compile Include="DrawTools\Rectangle.cs" />
5758
<Compile Include="DrawTools\Capsule.cs" />

0 commit comments

Comments
 (0)