Этот код работает только с монохромными (2 цветными, черно-белыми) изображениями.
public static class Processor
{
public static byte[] ToArray(this Bitmap bmp) // bitmap to byte array using lockbits
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr ptr = data.Scan0;
int numBytes = data.Stride * bmp.Height;
byte[] bytes = new byte[numBytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, numBytes);
bmp.UnlockBits(data);
return bytes;
}
public static int GetPixel(this byte[] array, int bpr, int x, int y) //find out if the given pixel is 0 or 1
{
int num = y * bpr + x / 8;
return (array[num] >> 7- x%8) & 1;
}
public static List<Point> getDrawingPoints(this Point start, byte[] array, int width, int height) // get one 0 point (black point) and find all adjacent black points by traveling neighbors
{
List<Point> points = new List<Point>();
points.Add(start);
int BytePerRow = array.Length / bmp.Height;
int counter = 0;
do
{
for (int i = Math.Max(0, points[counter].X - 1); i <= Math.Min(width - 1, points[counter].X + 1); i++)
for (int j = Math.Max(0, points[counter].Y - 1); j <= Math.Min(height - 1, points[counter].Y + 1); j++)
if (array.GetPixel(BytePerRow, i, j) == 0 && !points.Any(p => p.X == i && p.Y == j))
points.Add(new Point(i, j));
counter++;
} while (counter < points.Count);
return points;
}
public static Bitmap ToBitmap(this List<Point> points) // convert points to bitmap
{
int startX = points.OrderBy(p => p.X).First().X,
endX = points.OrderByDescending(p => p.X).First().X,
startY = points.OrderBy(p => p.Y).First().Y,
endY = points.OrderByDescending(p => p.Y).First().Y;
Bitmap bmp = new Bitmap(endX - startX + 1, endY - startY + 1);
Graphics g = Graphics.FromImage(bmp);
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, endX - startX - 1, endY - startY - 1));
for (int i = startY; i <= endY; i++)
for (int j = startX; j <= endX; j++)
if (points.Any(p => p.X == j && p.Y == i)) bmp.SetPixel(j - startX, i - startY, Color.Black);
return bmp;
}
}
И используйте его для получения всех чисел внутри основного изображения:
List<Point> processed = new List<Point>();
Bitmap bmp = ((Bitmap)Bitmap.FromFile(SourceBitmapPath));
byte[] array = bmp.ToArray();
int BytePerRow = array.Length / bmp.Height;
int imgIndex = 1;
for (int i = 0; i < bmp.Width; i++)
for (int j = 0; j < bmp.Height; j++)
{
if (array.GetPixel(BytePerRow, i, j) == 0 && !processed.Any(p => p.X == i && p.Y == j))
{
List<Point> points = new Point(i, j).getDrawingPoints(array, bmp.Width, bmp.Height);
processed.AddRange(points);
Bitmap result = points.ToBitmap();
result.Save($"{imgIndex++}.bmp");
}
}
Я использую рисование и монохромный формат BMP «Сохранить как» для генерации исходного изображения.
Я также протестировал его с этим изображением: ![enter image description here](https://i.stack.imgur.com/NGC9z.png)
, что привело кследующие три изображения:
![enter image description here](https://i.stack.imgur.com/ufjgC.png)
![enter image description here](https://i.stack.imgur.com/ODmoD.png)