C# — Создание BMP из байтов

Я создаю приложение WinForm на С#, которое я могу использовать для «вынюхивания» некоторых 24-битных растровых изображений в файле. Я уже собрал такую ​​информацию, как его смещение, некоторый анализ того, как он записан в файле, и его длину.

Итак, дополнительная информация о файле:

  • Данные BMP записываются в обратном порядке. (Пример: (255 0 0) записывается (0 0 255)
  • У него нет заголовка BMP. Только фрагменты данных изображения BMP.
  • PixelFormat 24-битный.
  • Его BMP чисто пурпурного цвета. (255 0 255 в RGB)

Я использую следующий код:

            using (FileStream fs = new FileStream(@"E:\MyFile.exe", FileMode.Open))
            {
                    int width = 190;
                    int height = 219;
                    int StartOffset = 333333;   // Just a sample offset

                    Bitmap tmp_bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                    Rectangle rect = new Rectangle(0, 0, tmp_bitmap.Width, tmp_bitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData =
                        tmp_bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        tmp_bitmap.PixelFormat);

                    unsafe
                    {
                        // Get address of first pixel on bitmap.
                        byte* ptr = (byte*)bmpData.Scan0;

                        int bytes = width * height * 3; //124830 [Total Length from 190x219 24 Bit Bitmap]

                        int b;  // Individual Byte

                        for (int i = 0; i < bytes; i++)
                        {
                            fs.Position = StartOffset - i;  // Change the fs' Position [Subtract since I'm reading in reverse]
                            b = fs.ReadByte();              // Reads one byte from its position

                            *ptr = Convert.ToByte(b);   // Record byte
                            ptr ++;
                        }
                        // Unlock the bits.
                        tmp_bitmap.UnlockBits(bmpData);
                    }
                    pictureBox1.Image =  tmp_bitmap;
                }

Я получаю этот вывод. Я думаю, причина в том, что байты путаются всякий раз, когда они достигают следующей строки. (255 0 255 становится 0 255 255 и так продолжается до тех пор, пока не станет 255 255 0)

Вывод

Надеюсь, вы поможете мне это исправить. Заранее большое спасибо.

РЕШЕНИЕ Теперь это исправлено путем добавления этого кода (с помощью моего друга и информации, предоставленной Джеймсом Холдернессом)

if (width % 4 != 0)
    if ((i + 1) % (width * 3) == 0 && (i + 1) * 3 % width < width - 1)
         ptr += 2;

Большое спасибо!


person CudoX    schedule 12.05.2013    source источник
comment
Я предполагаю, что проблема в том, что вы не используете bmpData.Stride в своем коде, в растровых данных пиксели, размещенные в строке, следуют друг за другом, но при изменении строки могут быть некоторые другие данные, которые не принадлежат пикселям, так что все идет неправильно, я опубликую ответ на этот вопрос   -  person Mehran    schedule 12.05.2013


Ответы (1)


Для стандартного BMP каждая отдельная строка сканирования должна быть кратна 4 байтам, поэтому, когда у вас есть 24-битное изображение (3 байта на пиксель), вам часто нужно разрешить заполнение в конце каждой строки сканирования, чтобы привести его до кратности 4.

Например, если ваша ширина равна 150 пикселям, это 450 байт, которые необходимо округлить до 452, чтобы сделать их кратными 4.

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

person James Holderness    schedule 12.05.2013
comment
Теперь это работает хорошо. Большое спасибо за вашу информацию! - person CudoX; 12.05.2013
comment
Превосходно. Рад, что смог помочь. - person James Holderness; 12.05.2013