【问题标题】:Trying to write 16-bit PNG尝试编写 16 位 PNG
【发布时间】:2012-05-30 09:48:17
【问题描述】:

我正在从相机捕捉图像,我有两个功能可以保存 16 位(!)图像,一个是 PNG 格式,一个是 TIFF 格式。 你能解释一下为什么PNG是一个非常嘈杂的图像吗?像这样:

PNG 函数:

 bool save_image_png(const char *file_name,const mono16bit& img)
{
    [...]
        /* write header */
        if (setjmp(png_jmpbuf(png_ptr)))
                abort_("[write_png_file] Error during writing header");

        png_set_IHDR(png_ptr, info_ptr, width, height,
                     bit_depth,PNG_COLOR_TYPE_GRAY , PNG_INTERLACE_NONE,
                     PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

        png_write_info(png_ptr, info_ptr);



        /* write bytes */
        if (setjmp(png_jmpbuf(png_ptr)))
                abort_("[write_png_file] Error during writing bytes");

    row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);

        for (y=0; y<height; y++)
            row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
     for (y = 0; y < height; y++)
     {
             row_pointers[y] = (png_bytep)img.getBuffer() + y * width*2;
     }



        png_write_image(png_ptr, row_pointers);


        /* end write */

  [...]           

}

和TIFF函数:

 bool save_image(const char *fname,const mono16bit& img)
{
  [...]

  for(y=0; y<height; y++) {
    if((err=TIFFWriteScanline(tif,(tdata_t)(img.getBuffer()+width*y),y,0))==-1)
      break;
  }

  TIFFClose(tif);

  if(err==-1) {
    fprintf(stderr,"Error writing to %s file\n",fname);
    return false;
  }
  return true;

//#endif //USE_LIBTIFF
}

谢谢!

【问题讨论】:

  • 我认为这是 C?如果需要,tiff 可以作为原始字节写出,但 png 是一种压缩格式,不能将原始相机输出转储到它。

标签: png tiff libpng


【解决方案1】:

png_set_swap 什么都不做。您必须在图像的每个像素中实际翻转字节。

如果您在 PC 上并且拥有 SSSE3 或更高版本,一个好方法是 _mm_shuffle_epi8 指令,使用 _mm_setr_epi8 创建一个置换向量。

如果您使用的是 ARM 并且有 NEON,请改用 vrev16q_u8 指令。

【讨论】:

    【解决方案2】:

    也许你有一个字节顺序问题。 尝试添加:

    png_set_swap(png_ptr);
    

    保存图片之前

    【讨论】:

    • 我把它放在 png_set_IHDR 之前,但得到了相同的结果.. (
    • 如果我把它放在 png_write_info 之后我得到了黑色图像
    • 添加 png_write_end(png_ptr, NULL); ?
    • 我有:png_write_image(png_ptr, row_pointers); /* end write */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); /* cleanup heap allocation */ // for (y=0; y&lt;height; y++) // free(row_pointers[y]); // free(row_pointers); fclose(fp);
    • 如果我把它放在 png_write_info 之后,我得到的不是黑色图像(tahnk ImageJ),但对于 16 位图像来说太暗了。最大强度为 959(在 ImageJ 中)。但为什么 16 位 TIFF 相同的数据看起来不一样..?
    猜你喜欢
    • 2012-02-07
    • 2021-12-22
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 2014-11-04
    • 2020-03-21
    • 2015-04-15
    • 1970-01-01
    相关资源
    最近更新 更多