如何用libpng编写16位的PNG_COLOR_TYPE_GRAY?

时间:2018-08-19 22:58:05

标签: macos libpng bit-depth

我编写了以下代码来生成黑白PNG图像,其中每个像素的值均为16位(0 =黑色,0xFFFF =白色)。这是一个简单的640x480测试图像,其中所有行都是相同的,并且左侧的每一行都有最大的黑色,向右逐渐变为白色。由于每行都是640像素宽,所以我期望看到几乎全黑的图像,在右侧最多可以看到640/65535的白色。相反,我得到的图像达到纯白色的2倍,分别对应于值0x00ff和0x01ff。这表明libpng不使用每个像素的最高有效字节。 有人可以告诉我我错了吗? 无论如何,感谢大家。 再见

系统和编译详细信息:

装有OS X 10.11.6的系统MacBook Pro(Retina,15英寸,2013年底)

PNG> gcc --version

配置有:--prefix = /应用程序/ Xcode.app /目录/开发人员/ usr --with-gxx-include-dir = /应用程序/ Xcode.app /目录/开发人员/平台/ MacOSX.platform /开发人员/ SDK / MacOSX10.12.sdk / usr / include / c ++ / 4.2.1 Apple LLVM版本8.0.0(clang-800.0.42.1) 目标:x86_64-apple-darwin15.6.0 螺纹型号:posix InstalledDir:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

PNG> gcc -I / opt / X11 / include / -L / opt / X11 / lib / -l png -l z writeTest16bit.c

生成的图像(file.png)为:enter image description here

/* This is the test code upper described */
#include <png.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define ERROR   -1

#define GOTO_ERROR {line = __LINE__; goto error;}

#define width     640
#define height    460
#define bit_depth 16
unsigned short int image[height][width];

void setBitMapImageGray (void);


int main (int argc, char **argv)
{ 
  char        *pngFileName = "file.png";
  FILE        *pngFile     = NULL;
  png_structp  pngStruct   = NULL;
  png_infop    pngInfo     = NULL;
  int          line        = __LINE__;
  int          i;
  setBitMapImageGray ();

  if (NULL == (pngFile   = fopen (pngFileName, "wb")))                                            GOTO_ERROR;
  if (NULL == (pngStruct = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))    GOTO_ERROR;
  if (NULL == (pngInfo   = png_create_info_struct (pngStruct)))                                   GOTO_ERROR; 

  // setting long jump: posponed

  png_init_io(pngStruct, pngFile);

  png_set_IHDR (pngStruct, pngInfo, width, height, bit_depth,
                PNG_COLOR_TYPE_GRAY,          PNG_INTERLACE_NONE,  
                PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

  png_write_info (pngStruct, pngInfo);

  for (i=0; i<height; i++)
    png_write_row (pngStruct, (png_const_bytep)&image[i][0]);
  png_write_end (pngStruct, NULL);

  png_destroy_write_struct (&pngStruct, (png_infopp)NULL);
  fclose (pngFile);

  return 0;

error:
  printf ("Error in line %d\n", line);
  if (pngStruct)  png_destroy_write_struct (&pngStruct, (png_infopp)NULL);
  if (pngFile)    fclose (pngFile);
  return (ERROR);
}

void setBitMapImageGray (void)
{
  int x,y;
  unsigned short int const black=0, step=0x10000/width;


  for (y=0;   y<height; y++) 
    for (x=0; x<width;  x++) 
//    image[y][x] = 0xFF00;
      image[y][x] = x;
}

1 个答案:

答案 0 :(得分:1)

您几乎是正确的-它不会忽略高字节,但是您会遇到字节顺序问题。

如果您在png_set_swap()之后添加png_write_info(),则您的代码可以正常工作

...
png_set_IHDR (pngStruct, pngInfo, width, height, bit_depth,
            PNG_COLOR_TYPE_GRAY,          PNG_INTERLACE_NONE,
            PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(pngStruct, pngInfo);

png_set_swap(pngStruct);    // <--- THIS LINE ADDED

...

enter image description here


关键字:PNG,libpng,16位,16位,灰度,字节序,字节序,字节序,小字节序,大字节序,写入,图像,图像处理,C。