Графическая ошибка при записи PNG из BITMAP в память - PullRequest
1 голос
/ 12 марта 2019

Я использую libpng для преобразования BITMAP в PNG (все в памяти), и он создает изображение, но с некоторыми визуальными ошибками.

enter image description here

Фон имеет вертикальную цветную линию, которая выглядит как голубой, пурпурный и желтый, а изображение растянуто по горизонтали, поэтому 1/4 отсутствует справа. BITMAP создается с использованием CDC и рисованием на CBitmap. Рисование выполняется в RGB , поэтому, когда BITMAP передается в функцию PNG , я использую BITMAPINFOHEADER с biCompression, установленным на BI_RGB. В настройках libpng я использовал 8 для битовой глубины и PNG_COLOR_TYPE_RGB. Первоначально я думал, что BITMAP находится в CMYK , что и вызвало проблему, но, похоже, в RGB . Может ли быть проблема конверсии? Когда я конвертирую то же Растровое изображение в JPEG все идеально.

BITMAPINFOHEADER :

BITMAPINFOHEADER oBitmapInfoHeader;
memset(&oBitmapInfoHeader, 0, sizeof(BITMAPINFOHEADER));
oBitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
oBitmapInfoHeader.biWidth = width;
oBitmapInfoHeader.biHeight = height * -1;
oBitmapInfoHeader.biPlanes = 1;
oBitmapInfoHeader.biBitCount = bitmap.bmPlanes * bitmap.bmBitsPixel; //initializes at 32
oBitmapInfoHeader.biCompression = BI_RGB;
oBitmapInfoHeader.biSizeImage = 0;
oBitmapInfoHeader.biXPelsPerMeter = 0;
oBitmapInfoHeader.biYPelsPerMeter = 0;
oBitmapInfoHeader.biClrUsed = 0;
oBitmapInfoHeader.biClrImportant = 0;

Я использую массив BYTE :

const uint32_t stride = width * 4;
png_byte *row = (png_byte *)poBitmapInfoHeader + (oBitmapInfoHeader.biSize + iColors * sizeof(RGBQUAD));

for (uint32_t y = 0; y < height; y++) {
    png_write_row(png_ptr, row);
    row += stride;
}

1 Ответ

0 голосов
/ 12 марта 2019

Я понял:

biBitCount действительно 24

oBitmapInfoHeader.biBitCount = 24;// bitmap.bmPlanes * bitmap.bmBitsPixel;

GetDIBits не удалось, потому что он начался слишком далеко

(LPBYTE)poBitmapInfoHeader + (oBitmapInfoHeader.biSize + iColors * 3),//sizeof(RGBQUAD)),   // address for bitmap bits

Затем шагс 3bpp работает

const uint32_t stride = (width * 3);
...