从内存中的 BITMAP 写入 PNG 时出现图形错误
Graphic bug when writing PNG from BITMAP in memory
我正在使用 libpng 将 BITMAP 转换为 PNG(全部在内存中),它确实创建了图像,但有一些视觉错误。
背景有一条垂直的彩色线条,看起来是青色、洋红色和黄色,并且图像水平展开,因此右侧缺失 1/4。 BITMAP 使用 CDC 创建并绘制到 CBitmap
。绘图是在 RGB 中完成的,所以当 BITMAP 传递给 PNG 函数时,我使用 BITMAPINFOHEADER,biCompression
设置为 BI_RGB
。在 libpng 设置中,我使用 8 作为位深度和 PNG_COLOR_TYPE_RGB
。我最初认为 BITMAP 在 CMYK 中,这是导致问题的原因,但它似乎在 RGB[=40= 中].会不会有转换问题?当我将相同的 Bitmap 转换为 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;
}
我想通了:
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);
我正在使用 libpng 将 BITMAP 转换为 PNG(全部在内存中),它确实创建了图像,但有一些视觉错误。
背景有一条垂直的彩色线条,看起来是青色、洋红色和黄色,并且图像水平展开,因此右侧缺失 1/4。 BITMAP 使用 CDC 创建并绘制到 CBitmap
。绘图是在 RGB 中完成的,所以当 BITMAP 传递给 PNG 函数时,我使用 BITMAPINFOHEADER,biCompression
设置为 BI_RGB
。在 libpng 设置中,我使用 8 作为位深度和 PNG_COLOR_TYPE_RGB
。我最初认为 BITMAP 在 CMYK 中,这是导致问题的原因,但它似乎在 RGB[=40= 中].会不会有转换问题?当我将相同的 Bitmap 转换为 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;
}
我想通了:
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);