libpng是一款C语言编写的比较底层的读写PNG文件的跨平台的库。借助它,你可以轻松读写PNG文件的每一行像素。
因为PNG文件是经过压缩而且格式复杂的图形文件(有的PNG文件甚至像GIF文件一样带动画效果)
而且PNG可以是带透明通道的真彩色图像、不带透明通道的真彩色图像、索引颜色、灰度颜色等各种格式,如果大家都自己写程序分析PNG文件就会显得很麻烦、很累。因此,通过使用libpng你就能直接使用现成的函数、程序来读写PNG文件了。
一: 安装PNG库文件
因为PNG文件需要用到zlib进行编解码, 所以用到libpng的同时也需要zlib加密解密
本文使用的是libpng版本和zlib版本如下:
下载地址:
LIBPNG: PNG reference library - Browse Files at SourceForge.net
libpng:
#解压
tar -xzvf libpng-1.6.26.tar.gz && cd libpng-1.6.26
#安装
./configure
make
sudo make install
sudo ldconfig
zlib:
#解压:
tar -xf zlib-1.2.11.tar.xz && cd zlib-1.2.11
#安装
./configure
make
sudo make install
怎样借助libpng读写PNG文件????
首先来讲如何写入PNG文件。
第一步:初始化libpng库。
当你需要读一个PNG文件或者写一个PNG文件的时候,你需要先定义两个结构体指针:
png_structp png_ptr=NULL;//libpng的结构体
png_infop info_ptr=NULL;//libpng的信息
你可以把上面的结构体指针定义为全局变量使用。
每这两个结构体对应一个PNG文件。因此当你要同时操作多个PNG文件的时候,你就需要定义多个png_structp和png_infop来处理这些PNG文件了。
因为是要写文件,所以要这样初始化:
int iRetVal;
png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
if(!png_ptr)
goto 错误处理;
info_ptr=png_create_info_struct(png_ptr);
if(!info_ptr)
{
png_destroy_write_struct(&png_ptr,NULL);
goto 错误处理;
}
iRetVal=setjmp(png_jmpbuf(png_ptr));//安装错误处理跳转点
//当libpng内部出现错误的时候,libpng会调用longjmp直接跳转到这里运行。
if(iRetVal)//setjmp的返回值就是libpng跳转后提供的错误代码(貌似总是1,但是还是请大家看libpng的官方文档)
{
fprintf(stderr,"错误码:%d\n",iRetVal);
goto 错误处理;
}
只要最后png_ptr和info_ptr都不是NULL就行了。否则就算是出错了。
这里可以看到libpng使用了setjmp来做错误处理。有关setjmp的信息请点这里进去看。
这两个结构体有对应的释放函数:png_destroy_write_struct
结束对一个PNG的访问之后,你只需像这样调用这个函数:
png_destroy_write_struct(&png_ptr,&info_ptr);
就可以了。
接下来打开文件准备写文件。还是大家熟悉的C语言文件流。
FILE*fp=fopen("C:\\TEST.PNG","wb");
if(!fp)
goto 错误处理;
打开了文件以后,你要让libpng和这个文件流绑定起来,因此你需要调用png_init_io来完成绑定。
png_init_io(png_ptr,fp);
接下来就是关键的部分了:设置PNG文件的属性、写入PNG文件头、写入PNG文件。
//设置PNG文件头
png_set_IHDR(png_ptr,info_ptr,
图像宽度,图像高度,//尺寸
8,//颜色深度,也就是每个颜色成分占用位数(8表示8位红8位绿8位蓝,如果有透明通道则还会有8位不透明度)
PNG_COLOR_TYPE_RGB,//颜色类型,PNG_COLOR_TYPE_RGB表示24位真彩深色,PNG_COLOR_TYPE_RGBA表示32位带透明通道真彩色
PNG_INTERLACE_NONE,//不交错。PNG_INTERLACE_ADAM7表