#
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
}
;
if
(
(
fp
=
fopen
(
path
,
"rb"
)
)
==
NULL
)
return
-
1
;
if
(
fread
(
buf
,
1
,
PNG_BYTES_TO_CHECK
,
fp
)
!=
PNG_BYTES_TO_CHECK
)
return
-
1
;
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_infop info_ptr
;
png_bytep
*
row_ptr
;
png_byte color_type
;
FILE
*
fp
=
NULL
;
if
(
(
fp
=
fopen
(
pPic
->
pathname
,
"rb"
)
)
==
NULL
)
{
fprintf
(
stderr
,
"fopen %s error.\n"
,
pPic
->
pathname
)
;
return
-
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
;
if
(
setjmp
(
png_jmpbuf
(
png_ptr
)
)
)
png_destroy_read_struct
(
&
png_ptr
,
&
info_ptr
,
NULL
)
;
fclose
(
fp
)
;
return
-
1
;
png_init_io
(
png_ptr
,
fp
)
;
png_read_png
(
png_ptr
,
info_ptr
,
PNG_TRANSFORM_EXPAND
|
PNG_TRANSFORM_STRIP_ALPHA
,
NULL
)
;
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
)
;
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
]
;
pPic
->
pData
[
pos
++
]
=
row_ptr
[
i
]
[
j
+
1
]
;
pPic
->
pData
[
pos
++
]
=
row_ptr
[
i
]
[
j
+
2
]
;
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
]
;
pPic
->
pData
[
pos
++
]
=
row_ptr
[
i
]
[
j
+
1
]
;
pPic
->
pData
[
pos
++
]
=
row_ptr
[
i
]
[
j
+
2
]
;
break
;
default
:
break
;
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
;
ret
=
is_png
(
pathname
)
;
if
(
ret
!=
0
)
{
return
-
1
;
pic
.
pathname
=
pathname
;
pic
.
pData
=
rgb_buf
;
ret
=
png_analyze
(
&
pic
)
;
if
(
ret
!=
0
)
{
return
-
1
;
fb_draw_jpg
(
0
,
0
,
&
pic
)
;
return
0
;
在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
png_uint_32 width;
png_uint_32 height;
png_uint_32 valid;
size_t rowbytes;
png_colorp palette;
png_uint_16 num_palette;
png_uint_16 num_trans;
png_byte bit_depth;
png_byte color_type;
png_byte compression_type;
png_byte filter_type;
png_byte interlace_type;
函数原型: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三通道。
#define PNG_TRANSFORM_IDENTITY 0x0000
#define PNG_TRANSFORM_STRIP_16 0x0001
#define PNG_TRANSFORM_STRIP_ALPHA 0x0002
#define PNG_TRANSFORM_PACKING 0x0004
#define PNG_TRANSFORM_PACKSWAP 0x0008
#define PNG_TRANSFORM_EXPAND 0x0010
#define PNG_TRANSFORM_INVERT_MONO 0x0020
#define PNG_TRANSFORM_SHIFT 0x0040
#define PNG_TRANSFORM_BGR 0x0080
#define PNG_TRANSFORM_SWAP_ALPHA 0x0100
#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200
#define PNG_TRANSFORM_INVERT_ALPHA 0x0400
#define PNG_TRANSFORM_STRIP_FILLER 0x0800
#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000
#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000
#define PNG_TRANSFORM_EXPAND_16 0x4000
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