我有一个使用 libpng 来读取和写入灰度和 RGB 图像的库。我的 BGR 和 RGB 图像已经有单独的 C++ 类型,但到目前为止,我一直在将 BGR 图像保存为 PNG 之前手动将其转换为 RGB。然后,当我读取时,我总是以 RGB 读取。
我想要做的是编写和读取我的图像,并且需要尽可能少的转换。如果我可以写出我的 BGR as BGR 并以这种方式读回它们,那就太理想了。
但是 libpng 文档在这件事上让我感到困惑。 RGB/BGR 信息实际上保存为图像格式本身吗?也就是说,当我打开 PNG 图像时,我可以询问 libpng 它是 RGB 还是 BGR 或者我必须提前知道吗?如果可以的话,我已经错过了可以让我使用的功能。我看到像 png_set_bgr 这样的函数和像 PNG_TRANSFORM_BGR 这样的转换标志,但我不确定使用它们的正确方法。
有人可以纠正我吗?
png_set_bgr
将RGB格式转换为BGR,例如:
int decode_png_from_file(FILE *fp, Bitmap *bitmap)
{
png_bytep *rows = NULL;
fseek(fp, 0, SEEK_SET);
memset(bitmap, 0, sizeof(*bitmap));
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png == NULL)
return -1;
png_infop info = png_create_info_struct(png);
if (info == NULL) {
png_destroy_read_struct(&png, NULL, NULL);
return -2;
}
int error = setjmp(png_jmpbuf(png));
if (error) {
png_destroy_read_struct(&png, &info, NULL);
if (bitmap->buffer != NULL) free(bitmap->buffer);
if (rows != NULL) free(rows);
return -3;
}
png_init_io(png, fp);
png_set_bgr(png);
png_read_info(png, info);
bitmap->width = png_get_image_width(png, info);
bitmap->rows = png_get_image_height(png, info);
bitmap->pitch = png_get_rowbytes(png, info);
bitmap->pixelMode = convert_color_type(png_get_color_type(png, info));
bitmap->buffer = (unsigned char *) malloc(bitmap->pitch * bitmap->rows);
if (bitmap->buffer == NULL) {
longjmp(png_jmpbuf(png), 1);
}
rows = (png_bytep *) malloc(sizeof(png_bytep) * bitmap->rows);
if (rows == NULL) {
longjmp(png_jmpbuf(png), 1);
}
unsigned int i = 0;
for (i = 0; i < bitmap->rows; i++) {
rows[i] = bitmap->buffer + i * bitmap->pitch;
}
png_read_image(png, rows);
png_destroy_read_struct(&png, &info, NULL);
free(rows);
return 0;
}