我必須PicureBox用純色填充里面的一個部分。我已經設法用這段代碼做到了:
private void fillForm(object sender, MouseEventArgs e)
{
MouseEventArgs me = (MouseEventArgs)e;
Point coordinates = me.Location; // get mouse click coordinates
Graphics graphics = Graphics.FromImage(imageSection.Image);
fillDownRight(coordinates);
fillUpLeft(new Point(coordinates.X - 1, coordinates.Y));
fillUpRight(new Point(coordinates.X, coordinates.Y - 1));
fillDownLeft(new Point(coordinates.X - 1, coordinates.Y 1));
graphics.Dispose();
imageSection.Refresh();
}
private void fillDownRight(Point coordinates)
{
Bitmap bitmap = ((Bitmap)imageSection.Image);
if (coordinates.Y < bitmap.Height && coordinates.X 1 < bitmap.Width)
{
int pixelColor = bitmap.GetPixel(coordinates.X, coordinates.Y).ToArgb();
if (pixelColor != Color.Black.ToArgb() && pixelColor != pen.Color.ToArgb())
{
bitmap.SetPixel(coordinates.X, coordinates.Y, pen.Color);
fillDownRight(new Point(coordinates.X, coordinates.Y 1));
fillDownRight(new Point(coordinates.X 1, coordinates.Y));
}
}
}
private void fillUpLeft(Point coordinates)
{
Bitmap bitmap = ((Bitmap)imageSection.Image);
if (coordinates.Y >= Constants.coordinatesZero && coordinates.X >= Constants.coordinatesZero)
{
int pixelColor = bitmap.GetPixel(coordinates.X, coordinates.Y).ToArgb();
if (pixelColor != Color.Black.ToArgb() && pixelColor != pen.Color.ToArgb())
{
bitmap.SetPixel(coordinates.X, coordinates.Y, pen.Color);
fillUpLeft(new Point(coordinates.X, coordinates.Y - 1));
fillUpLeft(new Point(coordinates.X - 1, coordinates.Y));
}
}
}
private void fillUpRight(Point coordinates)
{
Bitmap bitmap = ((Bitmap)imageSection.Image);
if (coordinates.Y >= Constants.coordinatesZero && coordinates.X < bitmap.Width)
{
int pixelColor = bitmap.GetPixel(coordinates.X, coordinates.Y).ToArgb();
if (pixelColor != Color.Black.ToArgb() && pixelColor != pen.Color.ToArgb())
{
bitmap.SetPixel(coordinates.X, coordinates.Y, pen.Color);
fillUpRight(new Point(coordinates.X, coordinates.Y - 1));
fillUpRight(new Point(coordinates.X 1, coordinates.Y));
}
}
}
private void fillDownLeft(Point coordinates)
{
Bitmap bitmap = ((Bitmap)imageSection.Image);
if (coordinates.Y < bitmap.Height && coordinates.X > Constants.coordinatesZero)
{
int pixelColor = bitmap.GetPixel(coordinates.X, coordinates.Y).ToArgb();
if (pixelColor != Color.Black.ToArgb() && pixelColor != pen.Color.ToArgb())
{
bitmap.SetPixel(coordinates.X, coordinates.Y, pen.Color);
fillDownLeft(new Point(coordinates.X - 1, coordinates.Y));
fillDownLeft(new Point(coordinates.X, coordinates.Y 1));
}
}
}
所以基本上我的代碼執行以下操作:
- 獲取我點擊的坐標
- 然后如果遞回地填充所有“空白”像素(沒有顏色),直到找到彩色/黑色像素
我PictureBox的樣子是這樣的:

如果我單擊所選區域:

PictureBox應該是這樣
的:
我想問是否有更快/更好的方法來填充該部分。
uj5u.com熱心網友回復:
我使用LinkedList<>. 使用Stack<>似乎更慢,因為它必須在填充時調整其內部陣列的大小。(源代碼Stack<>)
static class FloodFill
{
public static void Fill(this Bitmap bitmap, Color sourceColor,
Color newColor, int x, int y)
{
var sourceArgb = sourceColor.ToArgb();
var newArgb = newColor.ToArgb();
if (sourceArgb == newArgb)
{
return;
}
LinkedList<Point> list = new LinkedList<Point>();
list.AddLast(new Point(x, y));
do
{
x = list.Last.Value.X;
y = list.Last.Value.Y;
list.RemoveLast();
if (x < 0 || x >= bitmap.Width || y < 0 || y >= bitmap.Height)
{
list.RemoveLast();
continue;
}
if (bitmap.GetPixel(x, y).ToArgb() == sourceArgb)
{
bitmap.SetPixel(x, y, newColor);
list.AddLast(new Point(x 1, y));
list.AddLast(new Point(x - 1, y));
list.AddLast(new Point(x, y 1));
list.AddLast(new Point(x, y - 1));
}
}
while (list.Last != null);
}
}
客戶端代碼是
private void PictureBox1_MouseClick(object sender, MouseEventArgs e)
{
Bitmap bitmap = pictureBox1.Image as Bitmap;
bitmap.Fill(bitmap.GetPixel(e.X, e.Y), Color.Blue, e.X, e.Y);
pictureBox1.Invalidate();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/487102.html
上一篇:在Rider中添加.NET參考
