添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
# include <pngstruct.h> //解码库文件 # include <pnginfo.h> //解码库文件 # include <config.h> //自己定义的头文件 # define PNG_BYTES_TO_CHECK 8 *函数功能 :判断一个图片数是不是png图片 *函数参数 :path是图片文件的路径名加文件名 *返回值 :如果是png则返回0,不是或出错返回-1 static int is_png ( char * path ) { FILE * fp = NULL ; char buf [ PNG_BYTES_TO_CHECK ] = { 0 } ; /* Open the prospective PNG file. */ if ( ( fp = fopen ( path , "rb" ) ) == NULL ) return - 1 ; /* Read in some of the signature bytes */ if ( fread ( buf , 1 , PNG_BYTES_TO_CHECK , fp ) != PNG_BYTES_TO_CHECK ) return - 1 ; //比较头文件标识,是png格式则返回0,不是返回非0 //png 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A return ( png_sig_cmp ( buf , ( png_size_t ) 0 , PNG_BYTES_TO_CHECK ) ) ; *函数功能:解码png图片,并将解码出来的数据存储起来 *函数参数:pPic记录源png图片,解码出来图片宽高、位深度等 *返回值 :解码正确返回0,错误返回-1 static int png_analyze ( struct pic_info * pPic ) int i , j , pos = 0 ; png_structp png_ptr ; //定义一个png指针 png_infop info_ptr ; png_bytep * row_ptr ; //实际存储rgb数据的buf,二维指针 png_byte color_type ; FILE * fp = NULL ; if ( ( fp = fopen ( pPic -> pathname , "rb" ) ) == NULL ) { fprintf ( stderr , "fopen %s error.\n" , pPic -> pathname ) ; return - 1 ; //第1步:初始化相关结构体 png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING , NULL , NULL , NULL ) ; if ( png_ptr == NULL ) fprintf ( stderr , "init %s error.\n" , pPic -> pathname ) ; fclose ( fp ) ; return - 1 ; info_ptr = png_create_info_struct ( png_ptr ) ; if ( info_ptr == NULL ) fprintf ( stderr , "create %s error.\n" , pPic -> pathname ) ; fclose ( fp ) ; png_destroy_read_struct ( & png_ptr , NULL , NULL ) ; return - 1 ; //第2步:设置错误返回点 if ( setjmp ( png_jmpbuf ( png_ptr ) ) ) png_destroy_read_struct ( & png_ptr , & info_ptr , NULL ) ; fclose ( fp ) ; return - 1 ; //第3步:将解码的结构体和图片文件绑定 png_init_io ( png_ptr , fp ) ; //第4步:读文件 /*当内存足够大可以一次性读入所有的png数据,可以使用高层函数 该函数将会把所有的图片数据解码到info_ptr数据结构中*/ png_read_png ( png_ptr , info_ptr , PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA , NULL ) ; //第5步:提取打印文件信息 pPic -> width = info_ptr -> width ; pPic -> height = info_ptr -> height ; pPic -> bpp = info_ptr -> pixel_depth ; color_type = info_ptr -> color_type ; printf ( "picture resolution: %d*%d\n" , pPic -> width , pPic -> height ) ; printf ( "picture bpp: %d\n" , pPic -> bpp ) ; printf ( "picture colortype: %d\n" , color_type ) ; // 第6步: 读取真正的图像信息 row_ptr = png_get_rows ( png_ptr , info_ptr ) ; switch ( color_type ) { case PNG_COLOR_TYPE_RGB_ALPHA : for ( i = 0 ; i < pPic -> height ; i ++ ) { for ( j = 0 ; j < pPic -> width * 4 ; j + = 4 ) { pPic -> pData [ pos ++ ] = row_ptr [ i ] [ j + 0 ] ; // red pPic -> pData [ pos ++ ] = row_ptr [ i ] [ j + 1 ] ; // green pPic -> pData [ pos ++ ] = row_ptr [ i ] [ j + 2 ] ; // blue break ; case PNG_COLOR_TYPE_RGB : for ( i = 0 ; i < pPic -> height ; i ++ ) { for ( j = 0 ; j < pPic -> width * 3 ; j + = 3 ) { pPic -> pData [ pos ++ ] = row_ptr [ i ] [ j + 0 ] ; // red pPic -> pData [ pos ++ ] = row_ptr [ i ] [ j + 1 ] ; // green pPic -> pData [ pos ++ ] = row_ptr [ i ] [ j + 2 ] ; // blue break ; default : break ; //第7步:扫尾 png_destroy_read_struct ( & png_ptr , & info_ptr , 0 ) ; fclose ( fp ) ; return 0 ; int png_display ( char * pathname ) int ret = - 1 ; struct pic_info pic ; //第1步:判断图片是不是jpg图片 ret = is_png ( pathname ) ; if ( ret != 0 ) { return - 1 ; //第2步:显示jpg图片 pic . pathname = pathname ; pic . pData = rgb_buf ; ret = png_analyze ( & pic ) ; if ( ret != 0 ) { return - 1 ; fb_draw_jpg ( 0 , 0 , & pic ) ; return 0 ;

下面分析一下解码函数

1.png_infop 结构体在哪儿

在png.h的484行有如下内容,png_infop被声明为了png_info 的一维指针,而png_info又是png_info_def 的声明。

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_def后,接下来追根溯源,可以找到png_info_def定义在了pnginfo.h文件中:

struct png_info_def
   /* 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) */
   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 */
..................还有很长........

2.png_read_png()如何传参

函数原型:png_read_png(png_ptr, info_ptr, png_transforms, NULL)
读取图片文件信息有两种方法可以使用,一种是使用高层函数(high-level)读取,png_read_png()即为高层函数;另外一种是通过一系列的低层函数(low-level)接口进行读取操作,用起来相对麻烦。使用高层函数的前提是有足够的内存去存储整个图片的信息,因为高层函数内部进行了封装,所以使用起来很方便。
参数 png_transforms:可选用的值如下,如果只填参数PNG_TRANSFORM_EXPAND,那么转换结果为四通道,包含了RGB通道和ALPHA通道;参数改为PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA后,就可以把ALPHA通道屏蔽掉,转换之后即为RGB三通道。

/* Transform masks for the high-level interface */
#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* write only */
/* Added to libpng-1.2.34 */
#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
/* Added to libpng-1.4.0 */
#define PNG_TRANSFORM_GRAY_TO_RGB    0x2000     /* read only */
/* Added to libpng-1.5.4 */
#define PNG_TRANSFORM_EXPAND_16      0x4000     /* read only */

3.color_type的值有哪些

color_type的可能等于的值是由宏定义来决定的,switch判断的时候,我只判断了PNG_COLOR_TYPE_RGB_ALPHA和PNG_COLOR_TYPE_RGB两种情况,其他情况没有考虑,PNG_COLOR_TYPE_GRAY_ALPHA代表解码后的颜色类型为四通道,PNG_COLOR_TYPE_RGB代表三通道,转移数据的时候要注意这一点。

#define PNG_COLOR_TYPE_GRAY			0
#define PNG_COLOR_TYPE_RGB 			2
#define PNG_COLOR_TYPE_PALETTE 		3
#define PNG_COLOR_TYPE_GRAY_ALPHA	4
#define PNG_COLOR_TYPE_RGB_ALPHA	6
                                    它提供了无损PNG图片的编码和解码功能,并以简单、高效和高度灵活的设计而受到开发者们的欢迎。总之,无论你是初次接触图像处理,还是正在寻找一个新的PNG,LodePNG都值得一试。其简洁高效的设计和丰富的功能,无疑会为你的项目增添一份色彩。项目中的示例程序是很好的入门指南,可以帮助你快速理解如何进行PNG的读写和颜色转换等操作。嵌入式系统:对于内存有限或者计算能力有限的环境,LodePNG的简洁性和效率显得尤为重要。游戏开发:需要轻量级且高效的图像资源管理时,LodePNG是一个不错的选择。
                                    (1)zlib源码下载网址:http://www.zlib.net/;(2)libpng源码下载网址:ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng16/;(3)如果想直接要源码,可以私信我,源码和下面的移植过程是对应的;
                                    开源项目推荐:PNGdec——轻量级PNG图像解码
 PNGdecArduino PNG image decoder library项目地址:https://gitcode.com/gh_mirrors/pn/PNGdec 项目介绍
在数字化时代,图像处理变得至关重要,尤其是在资源受限的嵌入式系统中。PNGdec,由Larry Bank编写的开源项目,正是一座连接过去与未来的桥梁。自1980年代...
注意: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 &...
https://blog.csdn.net/weixin_38176039/article/details/82020865
1.在运行POM的C语言版本程序时,需要先安装Libpng,运行安装程序出现下面报错。
/usr/local/include/png.h:458:16: note: forward declaration of ‘pn...
                                    上文《图像解码之一——使用libjpeg解码jpeg图片》介绍了使用libjpeg解码jpeg图片png图片应用也非常广泛,本文将会简单介绍怎样使用开源libpng解码png图片libpng的数据结构
    png_structp变量是在libpng初始化的时候创建,由libpng内部使用,代表libpng的是调用上下文,使用者不应该对这个变量进行访问。调用li