便携式网络图形(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编译通过。
所有源码在附件中。
相关推荐
在本文中,我们将深入探讨如何使用 Libpng 配合 GDI(Graphics Device Interface)来解析和显示PNG图像。PNG(Portable Network Graphics)是一种无损压缩的位图格式,广泛应用于网页设计、软件开发以及图像处理等...
当一个PNG图像包含了一个与sRGB(标准红绿蓝)色彩空间不兼容的iCCP时,libpng库在解析时会发出警告,因为这可能导致颜色显示不准确。 出现“libpng warning: iCCP: known incorrect sRGB profile”错误的常见原因...
对于文件读取,通常会使用 `fopen` 打开文件,然后通过 `png_init_io` 函数将文件指针关联到 libpng: 1: fp = fopen(filename, "rb"); 2: if (!fp) 3: { 4: printf("Can't open %s\n", filename); 5: return ...
1. **读取PNG图像**:使用libpng库,可以解析PNG文件的元数据,如宽度、高度、色彩类型等,并解码图像数据。libpng提供了一系列API,如`png_read_image()`,可以读取像素数据到内存缓冲区。 2. **颜色空间转换**:...
- **加载PNG文件**:使用libpng提供的函数,如`png_create_read_struct`,`png_init_io`和`png_read_image`来读取PNG文件内容。 - **转换数据**:PNG图像数据通常以像素数组形式存在,需要将其转换为位图数据,...
在Qt中读取PNG图片,我们可以通过libpng库提供的函数来解析PNG文件,获取图像的像素数据。这些函数包括`png_create_read_struct`、`png_init_io`、`png_read_info`等,它们允许我们获取图像的宽度、高度、颜色类型等...
PNG(Portable Network Graphics)是一种广泛使用的无损压缩的位图图像格式,因其开源、免费、跨平台和良好的压缩效率而受到开发者的欢迎。`libpng`是官方支持的PNG库,用于读取、写入和处理PNG图像。在这个资源中,...
1. 加载PNG图像:使用libpng库解析PNG文件,解压缩数据并将其存储在内存中的适当数据结构。 2. 创建OpenGL纹理对象:在OpenGL上下文中创建一个新的纹理对象,并设置其属性。 3. 将图像数据上传到GPU:将内存中的PNG...
本文代码利用libpng库解码读取png图片,获取图片像素的颜色索引值,并将结果保存在opencv的Mat数据容器中。
4. **加载PNG到内存位图**:利用libpng解析出的像素数据,创建一个CBitmap对象,并将其绑定到兼容设备上下文。这个过程可能需要一些转换,因为MFC的CBitmap不直接支持Alpha通道,所以可能需要手动处理Alpha值。 5. ...
1. **PNG格式支持**:libpng提供读取和写入PNG图像文件的API,遵循PNG规范,确保正确解码和编码PNG数据流。 2. **错误处理**:库内包含丰富的错误检查和处理机制,以防止数据损坏或不完整时出现程序崩溃。 3. **内存...
2. **打开PNG文件**:使用`fopen`函数打开PNG文件,并通过libpng提供的`png_create_read_struct`和`png_create_info_struct`创建读取结构。 3. **设置错误处理回调**:libpng允许你定义错误处理函数,当出现错误时...
libpng,全称为“Library for Processing PNG”,是一个开源的PNG(Portable Network Graphics)图像处理库,广泛应用于各种软件和系统中,用于读取、写入和处理PNG格式的图像。libpng-1.6.26是该库的一个具体版本,...
1. **读取PNG图像**:libpng库提供了读取PNG文件的函数,能够解析PNG文件头信息,包括图像的宽度、高度、颜色类型、位深度等,并将图像数据解压缩到内存中。 2. **写入PNG图像**:库还允许开发者创建新的PNG图像或...
《深入解析libpng-1.2.40:PNG图像处理库的核心技术》 PNG(Portable Network Graphics)是一种无损压缩的位图格式,广泛应用于网页设计、软件开发以及数字图像处理等领域。libpng是PNG图像格式的开源库,它为...
这个项目提供了在Android应用中使用OpenGL ES显示PNG图片的一个实例,对于希望学习Android原生图形编程或者提升图形性能的开发者来说,是一个宝贵的参考资料。通过这种方式,开发者可以更高效地处理图像,为用户提供...
在OpenGL编程中,通常我们...总结来说,不使用libpng在OpenGL中加载PNG图标涉及读取PNG文件格式、解压数据、创建和更新纹理对象,以及在场景中正确绘制。提供的代码文件可能展示了这样一种实现,值得进一步研究和学习。
libpng负责解析PNG文件格式,而zlib则处理图像数据的压缩和解压缩。 在开发过程中,确保这些库文件正确配置和可用至关重要。对于libpng.lib和zlib.lib这样的静态库,开发者需要在编译项目时链接这些库;对于libpng...
- **读取PNG图像**:libpng库提供了解析PNG文件结构的功能,包括解码PNG图像数据、恢复颜色空间信息、处理透明度等。 - **写入PNG图像**:库允许开发者创建新的PNG文件,设定图像的大小、颜色模式、透明度等属性,...
《深入解析libpng-1.6.35:PNG图像处理的核心库》 PNG(Portable Network Graphics)是一种无损、有损压缩的位图格式,广泛应用于网页设计、图形编程和数字图像处理领域。在PNG图像处理的背后,有一个至关重要的库...