Преобразовать изображение в байтовую матрицу

Я пытаюсь сделать бинирацию для изображения (png), чтобы получить следующий результат, введите описание изображения здесь

для этого я использую следующий код, но сейчас я не могу получить ожидаемый результат, введите описание изображения здесь

который дает мне следующий результат, введите описание изображения здесь

2 ответа

Решение

Вы можете сделать это, он использует линии сканирования и блокировки, и это довольно быстро.

public unsafe static int[,] GetBits(string path )
{
   using (var orig = new Bitmap(path))
   {
      var bounds = new Rectangle(0, 0, orig.Width, orig.Height);    
      // lock the array for direct access
      var bitmapData = orig.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);

      try
      {
         // get the pointer
         var scan0Ptr = (int*)bitmapData.Scan0;    
         // get the stride
         var stride = bitmapData.Stride / 4;    
         // keep the black around
         var black = Color.Black.ToArgb();    
         //Output
         var array = new int[orig.Width, orig.Height];

         // scan all x first then y
         for (var y = 0; y < bounds.Bottom; y++)
            for (var x = 0; x < bounds.Right; x++)                     
               array[x, y] = *(scan0Ptr + x + y * stride) == black ? 0 : 1;

         return array;    
      }
      finally
      {
         // unlock the bitmap
         orig.UnlockBits(bitmapData);
      }    
   }
}

использование

var array = GetBits(@"d:\icon.png");

var w = array.GetLength(0);
var h = array.GetLength(1);

for (int i = 0; i < w; i++)
{
   for (int j = 0; j < h; j++)
      Console.Write(array[i,j]);
   Console.WriteLine();
}

Выход

00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00011111111111111111111111111000
00011111111111111111111111111000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000000000000000011000
00011000000000011111111111111000
00011000000000011111111111111000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011000000000011000000000011000
00011111111111111111111111111000
00011111111111111111111111111000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000

Исходное изображение 32х32

Чтобы сравнить два цвета, используйте ToArgb метод и лучше использовать StringBuilder вместо того, чтобы объединять каждый раз.
Это работает для меня:

var img = new Bitmap(pictureBox1.Image);
var sb = new StringBuilder();

for (int i = 0; i < img.Height; i++)
{
    for (int j = 0; j < img.Width; j++)
    {
        if (img.GetPixel(j, i).ToArgb() == Color.White.ToArgb())
        {
            sb.Append("0");
        }
        else
        {
            sb.Append("1");
        }
    }
}

richTextBox1.Text = sb.ToString();

Это приводит к большому количеству нулей и некоторых, моя картинка была большой, поэтому результат был некрасивым, но в вашем случае это должно сработать.

Другие вопросы по тегам