使用 libpng 过滤器

Posted

技术标签:

【中文标题】使用 libpng 过滤器【英文标题】:Using libpng filters 【发布时间】:2013-01-17 17:24:54 【问题描述】:

我想用 libpng 读取 PNG 文件,我想使用过滤器 png_set_rgb_to_gray_fixed 将 RGB 值转换为灰度。原始图像每个通道有 8 位,因此每个像素有 3 个字节。我希望输出为每像素 8 位。但是 png_get_rowbytes 告诉我行大小是 3*width。我做错了什么?

这是我的代码(为简洁起见,我删除了错误检查代码):

FILE *fp = fopen(filename,"rb");
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
png_infop info_ptr = png_create_info_struct(png_ptr);    
png_infop end_info = png_create_info_struct(png_ptr);
png_init_io(png_ptr, fp);
png_uint_32 width,height;
int color_depth,color_type, interlace_type, compression_type, filter_method;    
png_read_info(png_ptr, info_ptr);    
png_get_IHDR(png_ptr, info_ptr, &width, &height,
             &color_depth, &color_type, &interlace_type,
             &compression_type, &filter_method);
assert(color_type == PNG_COLOR_TYPE_RGB); 
png_set_rgb_to_gray_fixed(png_ptr, 3,-1,-1);

int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
assert(rowbytes == width ); // FAILS: rowbytes == 3*width

【问题讨论】:

【参考方案1】:

您需要拨打png_read_update_info:

png_read_update_info() 更新 info_ptr 指向的结构以反映已请求的任何转换。例如,将更新行字节以使用 png_read_update_info() 处理隔行扫描图像的扩展。

所以:

png_set_rgb_to_gray_fixed(png_ptr, 3,-1,-1);
png_read_update_info(png_ptr, info_ptr);
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);

【讨论】:

以上是关于使用 libpng 过滤器的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 libpng 加载图像时 Windows 上的运行时错误

如何使用 yum 安装 libpng?

使用 libpng 将位图缓冲区快速编码为 png

在c中使用libpng编写正弦波

libpng 错误:读取错误 (Visual Studio 2010)

mac下安装libpng环境