Я еще не очень разбираюсь в c # и должен написать алгоритм заливки, который также работает, когда есть небольшое изменение цвета (как тень на картинке).Я нашел четырехсторонний алгоритм на основе стека, который я изменил, чтобы также изменять пиксели, которые имеют немного другое значение в спектре RGB, чем предыдущий (вся часть "RGB-Test"), а не только область с однимцвет:
private void FloodFill2(Bitmap bmp, Point pt, Color targetColor, Color replacementColor)
{
Stack<Point> pixels = new Stack<Point>();
pixels.Push(pt);
while (pixels.Count > 0)
{
Point a = pixels.Pop();
if (a.X < bmp.Width && a.X > 0 &&
a.Y < bmp.Height && a.Y > 0)//make sure we stay within bounds
{
// RGB-Test Start
green = false;
red = false;
blue = false;
if (bmp.GetPixel(a.X, a.Y).G > targetColor.G)
{
if (targetColor.G - bmp.GetPixel(a.X, a.Y).G > (-20))
{
green = true;
}
}
else
{
if (bmp.GetPixel(a.X, a.Y).G - targetColor.G > (-20))
{
green = true;
}
}
if (bmp.GetPixel(a.X, a.Y).R > targetColor.R)
{
if (targetColor.R - bmp.GetPixel(a.X, a.Y).R > (-20))
{
red = true;
}
}
else
{
if (bmp.GetPixel(a.X, a.Y).R - targetColor.R > (-20))
{
red = true;
}
}
if (bmp.GetPixel(a.X, a.Y).B > targetColor.B)
{
if (targetColor.B - bmp.GetPixel(a.X, a.Y).B > (-20))
{
blue = true;
}
}
else
{
if (bmp.GetPixel(a.X, a.Y).B - targetColor.B > (-20))
{
blue = true;
}
}
// RGB-Test End
if (red == true && blue == true && green == true)
{
bmp.SetPixel(a.X, a.Y, replacementColor);
pixels.Push(new Point(a.X - 1, a.Y));
pixels.Push(new Point(a.X + 1, a.Y));
pixels.Push(new Point(a.X, a.Y - 1));
pixels.Push(new Point(a.X, a.Y + 1));
}
}
}
//refresh our main picture box
pictureBox1.Image = bmp;
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
return;
}
Проблема теперь в том, что он остановится, если градиент на изображении становится слишком сильным, что выглядит следующим образом: https://i.stack.imgur.com/15jhd.png
В качестве решения я подумализменения «targetColor» на новый цвет пикселя, который в данный момент изменяется, чтобы он мог «перемещаться» по градиенту и останавливаться только в том случае, если внезапно слишком велика разница в цвете.
Но здесь возникает проблема моего небольшого знания стеков и c # в целом, потому что при первой попытке изменить эту часть кода следующим образом
if (red == true && blue == true && green == true)
{
newColor = bmp.GetPixel(a.X, a.Y); // added this
bmp.SetPixel(a.X, a.Y, replacementColor);
pixels.Push(new Point(a.X - 1, a.Y));
pixels.Push(new Point(a.X + 1, a.Y));
pixels.Push(new Point(a.X, a.Y - 1));
pixels.Push(new Point(a.X, a.Y + 1));
targetColor = newColor; // and this
}
я получаю результаты, которые выглядят так: https://i.stack.imgur.com/U52mF.png
Это странно, потому что он делает именно то, что должен, но только не везде, где должен, и только в виде полос на картинке..
Я благодарю вас за каждое решение и другие идеи о том, как заставить эту работу работать правильно.