Создание файла BMP - PullRequest
       49

Создание файла BMP

1 голос
/ 26 марта 2011

Я некоторое время работал над обработкой изображений и заметил странные вещи.Я читаю файл BMP, использую простые методы, такие как ReadFile и прочее, и использую структуры Microsoft BMP.Вот код:

 ReadFile(_bmpFile,&bmpfh,sizeof(bfh),&data,NULL);
 ReadFile(_bmpFile, &bmpih, sizeof(bih), &data, NULL);
 imagesize = bih.biWidth*bih.biHeight;
 image = new RGBQUAD[imagesize];
 ReadFile(_bmpFile,image, imagesize*sizeof(RGBQUAD),&written,NULL);

Вот так я читаю файл и затем превращаю его в шкалу серого с помощью простого цикла for.

  for (int i = 0; i < imagesize; i++)
  {
       RED = image[i].rgbRed;
       GREEN = image[i].rgbGreen;
       BLUE = image[i].rgbBlue;
       avg = (RED + GREEN + BLUE ) / 3;
       image[i].rgbRed = avg;
       image[i].rgbGreen = avg;
       image[i].rgbBlue = avg;
  }

Теперь, когда язапишите файл, используя этот код:

#pragma pack(push, 1)
WriteFile(_bmpFile, &bmpfh, sizeof(bfh), &data, NULL);
WriteFile(_bmpFile, &bmpih, sizeof(bih), &data, NULL);
WriteFile(_bmpFile, image, imagesize*sizeof(RGBQUAD), &written, NULL);
#pragma pack(pop)

Файл становится намного больше (30 МБ -> 40 МБ).

Причина этого в том, что я использую RGBQUAD вместо RGBTRIPLE, ноесли я использую RGBTRIPLE, у меня проблема с преобразованием маленьких картинок в оттенки серого - не могу открыть картинку после ее создания (говорит, что она не в правильной структуре).

Такжеразмер файла пропускает один байт (1174 КБ и после 1173 КБ)

Кто-нибудь видел это раньше (это происходит только с небольшими картинками)?

Ответы [ 3 ]

3 голосов
/ 26 марта 2011

В файле BMP каждая строка сканирования должна быть дополнена, чтобы следующая строка сканирования начиналась с 32-битной границы. Если вы делаете 32 бита на пиксель, это происходит автоматически, но если вы используете 24 бита на пиксель, вам нужно добавить код, чтобы сделать это явно.

2 голосов
/ 26 марта 2011

Вы игнорируете шаг (комментарий Джерри) и формат пикселя растрового изображения. Что, если судить по увеличению размера файла, составляет 24 бит / с, то вы пишете так, словно оно составляет 32 бит / с. Ваше преобразование в оттенках серого неверно, человеческий глаз не одинаково чувствителен к красному, зеленому и синему.

Подумайте об использовании GDI +, вы #include <gdiplus.h> в своем коде для использования класса Bitmap. Его метод LockBits () дает вам доступ к битам битовой карты. Класс ColorMatrixEffect позволяет применять преобразование цвета в одной операции. Отметьте этот ответ для цветовой матрицы, которая необходима для получения изображения в оттенках серого. Документы MSDN начинаются здесь .

0 голосов
/ 17 января 2015

Каждая горизонтальная строка в BMP должна быть кратна 4 байтам.

Если данные пикселей не занимают кратные 4 байта, то 0x00 байт добавляются в концеряд.Для изображения с 24 битами на канал число байтов в строке составляет (imageWidth * 3 + 3) & ~ 3.Число байтов заполнения равно ((imageWidth * 3 + 3) & ~ 3) - (imageWidth * 3).

На этот вопрос ответил immibis.

Я хотел быдобавьте, что размер массива равен ((imageWidth * 3 + 3) и ~ 3) * imageHeight.Я надеюсь, что это помогает

...