使用libpng读写PNG图片

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位真彩深色&
  • 6
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
1. 首先,需要安装libpng库,可以通过以下命令在Ubuntu上安装: ``` sudo apt-get install libpng-dev ``` 2. 接下来,需要编写一个C程序来读取PNG图像。以下是一个简单的程序示例: ```c #include <stdio.h> #include <stdlib.h> #include <png.h> int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <filename>\n", argv[0]); return 1; } char *filename = argv[1]; FILE *fp = fopen(filename, "rb"); if (!fp) { printf("Failed to open %s\n", filename); return 1; } png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { printf("Failed to create PNG read struct\n"); fclose(fp); return 1; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { printf("Failed to create PNG info struct\n"); png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(fp); return 1; } png_init_io(png_ptr, fp); png_read_info(png_ptr, info_ptr); int width = png_get_image_width(png_ptr, info_ptr); int height = png_get_image_height(png_ptr, info_ptr); png_byte color_type = png_get_color_type(png_ptr, info_ptr); png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr); printf("Image size: %d x %d\n", width, height); printf("Color type: %d\n", color_type); printf("Bit depth: %d\n", bit_depth); png_bytep row_pointers[height]; for (int y = 0; y < height; y++) { row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr, info_ptr)); } png_read_image(png_ptr, row_pointers); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { png_bytep pixel = &(row_pointers[y][x * 4]); printf("(%d,%d): %d %d %d %d\n", x, y, pixel[0], pixel[1], pixel[2], pixel[3]); } } for (int y = 0; y < height; y++) { free(row_pointers[y]); } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); return 0; } ``` 3. 编译程序: ``` gcc -o read_png read_png.c -lpng ``` 4. 运行程序: ``` ./read_png example.png ``` 注意,以上示例程序仅供参考,实际应用中需要根据具体需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值