Вы можете найти первую точку каждой формы, которая заполняет другую область на растровом изображении, прочитать одну горизонтальную строку, чтобы получить точки данного цвета, затем l oop по вертикали в пределах горизонтального диапазона, чтобы получить соседние точек.
После того, как вы получите все точки для каждой, вы можете вычислить ограничивающий прямоугольник через первую и последнюю точки.
public static IEnumerable<Rectangle> GetColorRectangles(Bitmap src, Color color)
{
var rects = new List<Rectangle>();
var points = new List<Point>();
var srcRec = new Rectangle(0, 0, src.Width, src.Height);
var srcData = src.LockBits(srcRec, ImageLockMode.ReadOnly, src.PixelFormat);
var srcBuff = new byte[srcData.Stride * srcData.Height];
var pixSize = Image.GetPixelFormatSize(src.PixelFormat) / 8;
Marshal.Copy(srcData.Scan0, srcBuff, 0, srcBuff.Length);
src.UnlockBits(srcData);
Rectangle GetColorRectangle()
{
var curX = points.First().X;
var curY = points.First().Y + 1;
var maxX = points.Max(p => p.X);
for(var y = curY; y < src.Height; y++)
for(var x = curX; x <= maxX; x++)
{
var pos = (y * srcData.Stride) + (x * pixSize);
var blue = srcBuff[pos];
var green = srcBuff[pos + 1];
var red = srcBuff[pos + 2];
if (Color.FromArgb(red, green, blue).ToArgb().Equals(color.ToArgb()))
points.Add(new Point(x, y));
else
break;
}
var p1 = points.First();
var p2 = points.Last();
return new Rectangle(p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y);
}
for (var y = 0; y < src.Height; y++)
{
for (var x = 0; x < src.Width; x++)
{
var pos = (y * srcData.Stride) + (x * pixSize);
var blue = srcBuff[pos];
var green = srcBuff[pos + 1];
var red = srcBuff[pos + 2];
if (Color.FromArgb(red, green, blue).ToArgb().Equals(color.ToArgb()))
{
var p = new Point(x, y);
if (!rects.Any(r => new Rectangle(r.X - 2, r.Y - 2,
r.Width + 4, r.Height + 4).Contains(p)))
points.Add(p);
}
}
if (points.Any())
{
var rect = GetColorRectangle();
rects.Add(rect);
points.Clear();
}
}
return rects;
}
Демо
private IEnumerable<Rectangle> shapesRects = Enumerable.Empty<Rectangle>();
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
var sx = 1f * pictureBox1.Width / pictureBox1.ClientSize.Width;
var sy = 1f * pictureBox1.Height / pictureBox1.ClientSize.Height;
var p = Point.Round(new PointF(e.X * sx, e.Y * sy));
var c = (pictureBox1.Image as Bitmap).GetPixel(p.X, p.Y);
shapesRects = GetColorRectangles(pictureBox1.Image as Bitmap, c);
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (shapesRects.Any())
using (var pen = new Pen(Color.Black, 2))
e.Graphics.DrawRectangles(pen, shapesRects.ToArray());
}
SOA62875861