便携式网络图形(Portable Network Graphics,PNG)是一种无损压缩的位图图形格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。PNG的开发目标是改善并取代GIF作为适合网络传输的格式而不需专利许可,所以被广泛应用于互联网及其他方面上。
详细结构可以参照维基百科:http://zh.wikipedia.org/wiki/PNG
最常用的libpng库提供了解析png所需要的方法,不需要详细掌握png的文件结构,就可以调用相关函数获取png图片基本信息和解压后的图像数据以便后续使用。
libpng官方网站:http://libmng.com/pub/png/libpng.html
依赖库zlib官方网站:http://www.zlib.net/
使用libpng常用两个结构体:
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * * png_struct is the cache of information used while reading or writing a single * PNG file. One of these is always required, although the simplified API * (below) hides the creation and destruction of it. */ typedef struct png_struct_def png_struct; typedef const png_struct * png_const_structp; typedef png_struct * png_structp; typedef png_struct * * png_structpp; /* png_info contains information read from or to be written to a PNG file. One * or more of these must exist while reading or creating a PNG file. The * information is not used by libpng during read but is used to control what * gets written when a PNG file is created. "png_get_" function calls read * information during read and "png_set_" functions calls write information * when creating a PNG. * been moved into a separate header file that is not accessible to * applications. Read libpng-manual.txt or libpng.3 for more info. */ typedef struct png_info_def png_info; typedef png_info * png_infop; typedef const png_info * png_const_infop; typedef png_info * * png_infopp;
png_info结构体中包含一些图片的相关信息:尺寸,位深等:
/* The following are necessary for every PNG file */ png_uint_32 width; /* width of image in pixels (from IHDR) */ png_uint_32 height; /* height of image in pixels (from IHDR) */ png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ png_size_t rowbytes; /* bytes needed to hold an untransformed row */ png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ /* The following three should have been named *_method not *_type */ png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ /* The following are set by png_set_IHDR, called from the application on * write, but the are never actually used by the write code. */ png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ png_byte pixel_depth; /* number of bits per pixel */ png_byte spare_byte; /* to align the data, and for future use */
下面是最简单的使用libpng读取并用opengl显示图片的代码:
/* * pngtest.c * * Created on: 2014-10-27 * Author: HZY */ #include <stdio.h> #include <stdlib.h> #include "png.h" #include "zlib.h" #include "GL/freeglut.h" unsigned char* buffer = NULL; png_uint_32 width, height, color_type; //获取每一行所用的字节数,需要凑足4的倍数 int getRowBytes(int width){ //刚好是4的倍数 if((width * 3) % 4 == 0){ return width * 3; }else{ return ((width * 3) / 4 + 1) * 4; } } //显示图片 void myDisplay() { glClear(GL_COLOR_BUFFER_BIT); //图片是否有透明度 if (color_type == PNG_COLOR_TYPE_RGB) { glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer); } else if (color_type == PNG_COLOR_TYPE_RGBA) { glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); } glFlush(); } int main(int c, char** v) { png_structp png_ptr; png_infop info_ptr; int bit_depth; FILE *fp; printf("lpng[%s], zlib[%s]\n", PNG_LIBPNG_VER_STRING, ZLIB_VERSION); if ((fp = fopen("testrgb.png", "rb")) == NULL) { return EXIT_FAILURE; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); return EXIT_FAILURE; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, NULL, NULL); return EXIT_FAILURE; } if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return EXIT_FAILURE; } /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, fp); //读取png文件 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0); //获取png图片相关信息 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); printf("width[%d], height[%d], bit_depth[%d], color_type[%d]\n", width, height, bit_depth, color_type); //获得所有png数据 png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr); //计算buffer大小 unsigned int bufSize = 0; if (color_type == PNG_COLOR_TYPE_RGB) { bufSize = getRowBytes(width) * height; } else if (color_type == PNG_COLOR_TYPE_RGBA) { bufSize = width * height * 4; } else{ return EXIT_FAILURE; } //申请堆空间 buffer = (unsigned char*) malloc(bufSize); int i; for (i = 0; i < height; i++) { //拷贝每行的数据到buffer, //opengl原点在下方,拷贝时要倒置一下 if(color_type == PNG_COLOR_TYPE_RGB){ memcpy(buffer + getRowBytes(width) * i, row_pointers[height - i - 1], width * 3); }else if(color_type == PNG_COLOR_TYPE_RGBA){ memcpy(buffer + i * width * 4, row_pointers[height - i - 1], width * 4); } } png_destroy_read_struct(&png_ptr, &info_ptr, 0); fclose(fp); glutInit(&c, v); glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE); glutInitWindowPosition(100, 100); glutInitWindowSize(width, height); glutCreateWindow("hello png"); glutDisplayFunc(&myDisplay); glutMainLoop(); return 0; }
效果如图:
能显示RGB图片和RGBA的图片,代码里做了判断,用到了libpng,zlib,freeglut。在eclipse中cdt用mingw编译通过。
所有源码在附件中。
相关推荐
png+libpng.lib+libpng16.dll+zlib.lib四个C语言使用libPNG开发需要用到的 一:libpng库的编译 环境:windows10 + VS2013 需要下载:libpng, zlib两个库 下载地址: libpng:...
首先下载两个库, 一个是 libpng , 另一个则是 zlib 库, zlib 库是一套用于压缩数据的库, libpng 借助了该库作为压缩引擎, 也就是说, libpng 依赖于 zlib 库。
本文代码利用libpng库解码读取png图片,获取图片像素的颜色索引值,并将结果保存在opencv的Mat数据容器中。
报错libpng warning: iCCP: known incorrect sRGB profile的问题
libpng图像解析
3、设置错误返回点 上文libjpeg解码jpeg图片中提到用setjmp/longjmp函数来处理异常 4、设置libpng的数据源 我在上文《图
图片资源中有一个不是 png 格式图片, 这个png 格式并不是只指 尾缀名 为 ".png" 的图片。 可通过 java代码 检查 是否为png 格式。
GL2libpng-android-显示PNG图片.rar GL2libpng-android-显示PNG图片.rar
能将png格式图片转换成YUV格式。 C++实现,并且自带可运行实例。
资源里面是标准的png源码,其中包含全部代码和说明文档
VS2015编译的png库的64位库,版本是1.6.37。libpng是一款C语言编写的比较底层的读写PNG文件的跨平台的库。借助它,你可以轻松读写PNG文件的每...因此,通过使用libpng你就能直接使用现成的函数、程序来读写PNG文件了。
Gzip Zlib PNG 压缩算法,包含了png压缩的方式和格式,libpng等应用,主要是deflate算法
本资源用于png贴图的使用,里面直接包含了dll和lib等相关文件,不用重新生成dll文件
libpng是一款C语言编写的比较底层的读写PNG文件的跨平台的库。借助它,你可以轻松读写PNG文件的每一行像素。 因为PNG文件是经过压缩而且格式...因此,通过使用libpng你就能直接使用现成的函数、程序来读写PNG文件了。
Ygloo-external-libpng 是雅虎扩展的一个 PNG 图像处理库。如果想获得 UNIX 风格的行结尾,你可以在 text 文件中通过它获得 libpng-*.tar.gz 或者 libpng-*.tar.xz,如果你想获得 DOS 风格的行结尾,你可以获得 lpng...
A description on how to use and modify libpng libpng version 1.2.5 - October 3, 2002
libpng是多种应用程序使用的解析PNG图象格式的库。
MFC利用libpng源码库显示PNG图片
libpng 用于处理 png 格式的图片, 是一套比较完善的 png 图片处理库, 免费、开源, 因此受到了很高的好评。当需要利用qrencode生成二维码的时候,这个版本可以和Zlib-1.2.8,qrencode-3.4.4版本,共同作用生成想要的...
动画便携式网络图形(APNG)是便携式网络图形(PNG)格式的非官方扩展。 APNG修补程序为libpng提供APNG支持。