【发布时间】:2016-04-23 22:21:11
【问题描述】:
我有一个每通道 16 位的真彩色图像(由 ImageMagick 创建),我想将其读入单独的 R、G、B 平面。问题是生成的 16 位像素值只是复制了结果中的低字节和高字节。例如,如果红色分量的近似值为 0x42,那么我的 libpng 代码实际上返回的值是 0x4242。
我的第一个问题是我不太相信输入实际上有 16 位像素。这是identify -verbose 返回的内容:
Type: TrueColor
Endianess: Undefined
Colorspace: RGB
Depth: 16/8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Red:
min: 0 (0)
max: 65535 (1)
Properties:
PNG:IHDR.bit_depth : 16
PNG:IHDR.color_type : 2
这张图片是否真的有我可以提取的 16 位数据?如果是这样,怎么做?我的libpng读取代码基本上是这样的(确认png_get_color_type返回2,png_get_bit_depth返回16后):
png_uint_32 rowbytes = png_get_rowbytes(png, info);
image = (png_byte *) xmalloc(height * rowbytes);
row_pointers = (png_bytep*) xmalloc(sizeof(png_bytep) * height);
for(int i = 0; i < (int)height; i++)
row_pointers[i] = image + (i*rowbytes);
png_read_image(png, row_pointers);
我的代码将image 拆分为 RGB 平面是这样做的:
uint16_t *src = (uint16_t*) image; // libpng composite image
uint16_t *rplane, *gplane, *bplane; // separate planar channels
...
for(size_t i=0; i<nrows; i++) {
for(size_t j=0; j<ncols; j++) {
*rplane++ = *src++;
*gplane++ = *src++;
*bplane++ = *src++;
}
}
所以这里假设 libpng 返回的 48 位像素数据是 16b R,然后是 16b B,然后是 16b G。
如果我将图像读入 Matlab,它会报告由于 ImageMagick 的限制,它只能读取 8-b 像素。 如果 Matlab 报告像素 (x,y) 的红色分量为 0x42,例如,上面的 libpng 代码报告它的值为 0x4242。然而,Matlab 和上面的 libpng 代码同意所有像素的 RGB 值,除了 Matlab 将它们全部报告为单个 8 位分量,并且 libpng 代码在每个 16 位中复制该值两次组件。
有什么想法吗?谢谢。
编辑
非详细identify 输出:
> identify in.png
in.png PNG 2776x2776 2776x2776+0+0 16-bit DirectClass 14.35MB 0.000u 0:00.000
【问题讨论】:
标签: imagemagick libpng