注意:libpng使用需要用到zlib库,因此需要安装zlip库
libpng库链接:https://libpng.sourceforge.io/index.html
zlib库链接:https://libpng.sourceforge.io/index.html
二、ubuntu上安装libpng解压:tar -xzvf libpng-1.6.37.tar.gz && cd libpng-1.6.37
解压后的文件目录如下图
下一步进行libpng安装
./configure && make && make install
三、ubuntu上安装zlib解压:tar -xzvf zlib-1.2.11.tar.gz && cd zlib-1.2.11
解压后的文件目录如下图
下一步进行zlib安装
./configure && make && make install
四、在ubuntu系统上验证将png解码为rgb参考库自带的sample-png2pnm.c并简写,代码如下:
#include#include #include #include #include "png.h" #ifndef BOOL #define BOOL unsigned char #endif #ifndef TRUE #define TRUE (BOOL) 1 #endif #ifndef FALSE #define FALSE (BOOL) 0 #endif BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha); int main (int argc, char *argv[]) { FILE *fp_rd = stdin; FILE *fp_wr = stdout; FILE *fp_al = NULL; BOOL raw = TRUE; BOOL alpha = FALSE; if((fp_rd = fopen ("test.png", "rb")) == NULL){ printf("fopen png errorn"); exit (1); } if ((fp_wr = fopen ("test.rgb", "wb")) == NULL){ printf("fopen rgb errorn"); exit (1); } printf("%d %dn",alpha,raw); if (png2pnm (fp_rd, fp_wr, fp_al, 1, 0) == FALSE){ printf("decode rgb errorn"); exit (1); } fclose (fp_rd); fclose (fp_wr); return 0; } BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,BOOL raw, BOOL alpha) { png_struct *png_ptr = NULL; png_info *info_ptr = NULL; png_byte buf[8]; png_byte *png_pixels = NULL; png_byte **row_pointers = NULL; png_byte *pix_ptr = NULL; png_uint_32 row_bytes; png_uint_32 width; png_uint_32 height; int bit_depth; int channels; int color_type; int row, col; int ret; int i; struct timeval start; struct timeval end1; struct timeval end2; unsigned long timer; gettimeofday(&start,NULL); ret = fread (buf, 1, 8, png_file); if (ret != 8){ return FALSE; } ret = png_sig_cmp (buf, 0, 8); if (ret != 0){ return FALSE; } png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),NULL, NULL, NULL); if (!png_ptr){ return FALSE; } info_ptr = png_create_info_struct (png_ptr); if (!info_ptr){ png_destroy_read_struct (&png_ptr, NULL, NULL); return FALSE; } if (setjmp (png_jmpbuf (png_ptr))){ png_destroy_read_struct (&png_ptr, &info_ptr, NULL); return FALSE; } png_init_io (png_ptr, png_file); png_set_sig_bytes (png_ptr, 8); png_read_info (png_ptr, info_ptr); png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,NULL, NULL, NULL); png_read_update_info (png_ptr, info_ptr); 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:%dn",width,height,bit_depth,color_type); if (color_type == PNG_COLOR_TYPE_GRAY){ channels = 1; }else if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA){ channels = 2; }else if (color_type == PNG_COLOR_TYPE_RGB){ channels = 3; }else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA){ channels = 4; }else{ channels = 0; } gettimeofday(&end1,NULL); row_bytes = png_get_rowbytes (png_ptr, info_ptr); timer = 1000000 * (end1.tv_sec-start.tv_sec)+ end1.tv_usec-start.tv_usec; printf("timer = %ld usn",timer); printf("row_bytes :%dn",row_bytes); if ((png_pixels = (png_byte *) malloc ((size_t) row_bytes * (size_t) height)) == NULL){ png_destroy_read_struct (&png_ptr, &info_ptr, NULL); return FALSE; } if ((row_pointers = (png_byte **)malloc ((size_t) height * sizeof (png_byte *))) == NULL){ png_destroy_read_struct (&png_ptr, &info_ptr, NULL); free (png_pixels); return FALSE; } for (i = 0; i < ((int) height); i++){ row_pointers[i] = png_pixels + i * row_bytes; } png_read_image (png_ptr, row_pointers); gettimeofday(&end2,NULL); timer = 1000000 * (end2.tv_sec-end1.tv_sec)+ end2.tv_usec-end1.tv_usec; printf("timer = %ld usn",timer); png_read_end (png_ptr, info_ptr); png_destroy_read_struct (&png_ptr, &info_ptr, NULL); pix_ptr = png_pixels; printf("raw:%d,channels:%dn",raw,channels); for (row = 0; row < (int) height; row++){ for (col = 0; col < (int) width; col++){ for (i = 0; i < channels; i++){ fputc (*pix_ptr++, pnm_file); } } } if (row_pointers != NULL){ free (row_pointers); } if (png_pixels != NULL){ free (png_pixels); } return TRUE; }
结果如下(注意我的代码只适用于PNG24和PNG8(项目需要),PNG32或PNG16需要添加一点代码,这里自己可以去看sample:
五、往其它架构的嵌入式开发板上移植libpnglibpng已经帮我们提供了只用于解码或者编码的源文件
cd contrib/pngminim目录,选择需要使用libpng的功能
例如这里我只需要使用解码功能,cd decoder && make,这里会提示你缺少zlib库的文件,如下图
需要你把zlib库里面的源文件和头文件依次拷贝到decoder目录下,这里缺少的文件有:
zlib.h、crc32.h、inffast.h、inffixed.h、inflate.h、inftrees.h、zutil.h、zconf.h、adler32.c、crc32.c、inffast.c、inflate.c、inftrees.c、zutil.c
将缺少的源文件和头文件拷贝,进行make,生成png2pnm可执行程序,如下图:
目录里面的源文件和头文件即解码需要的所有源文件和头文件,后续可以根据嵌入式平台配置不同的交叉编译工具进行编译,encoder同decoder步骤



