1、zlib库和png库的源码获取
(1)zlib库源码下载网址:http://www.zlib.net/;
(2)libpng库源码下载网址:ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng16/;
(3)如果想直接要源码,可以私信我,源码和下面的移植过程是对应的;
2、libpng库的移植步骤
(1)首先要编译zlib库,因为libpng库是依赖zlib库;
(2)将编译得到的zlib库和头文件存放路径导出到环境变量,这样在编译libpng库时可以直接使用;
(3)编译libpng库,得到动态库和头文件,并移植到自己的工程环境中;
(4)根据libpng库源码中的example.c示例代码,编写png图片的编解码函数;
3、zlib库的编译
解压源码:
tar -zxvf zlib-1.2.8.tar.gz
导出交叉编译工具链:
export CC=arm-linux-gcc
配置源码,生成Makefile:
./configure -shared --prefix=/opt/pngDecode
-shared:生成动态库
--prefix:安装路径
编译和安装:
make && make install
(1)解压源码:tar -zxvf zlib-1.2.8.tar.gz;
(2)导出交叉编译工具链:export CC=arm-linux-gcc;
(3)配置zlib库:./configure -shared --prefix=/opt/pngDecode;
(4)经过第三步会得到Makefile文件,执行命令:make && make install;
(5)在/opt/pngDecode目录下会生成include和lib文件夹,里面是zlib库的头文件和动态库;
4、libpng库源码编译
解压源码:
tar -zxvf libpng-1.6.6.tar.gz
第一步:
export LDFLAGS="-L/opt/pngDecode/lib"
export CFLAGS="-I/opt/pngDecode/include"
export CPPFLAGS="-I/opt/pngDecode/include"
第二步:
./configure --host=arm-linux --enable-shared --enable-static --prefix=/opt/jpgDecode
--host:指定目标平台
--enable-shared:生成动态库
--enable-static:生成静态库
--prefix:指定安装目录,将来产物就存放在此路径
第三步:
make && make install
(1)首先将zlib库的头文件和动态库路径导出到环境变量中,供libpng库的编译使用;
(2)调用configure文件配置libpng源码,生成Makefile文件;
(3)调用Makefile文件编译源码和安装zlib库;
5、png解码库的移植
(1)将编译得到的include目录下的头文件,和lib目录下动态库添加到你的代码工程中,并且动态库还需要部署到可执行程序的运行环境中;
(2)参考libpng源码中的example.c示例代码,编写调用png解码库去编解码png图片的函数;
(3)在实际编写png解码函数后会发现,还需要pngstruct.h和pnginfo.h,都在libpng库的源码中,拷贝过去即可;
6、png解码库的使用示例
// 结构体用来封装一个图片的各种信息
typedef struct pic_info
{
char *pathname; // 图片在文件系统中的路径名+文件名
unsigned int width; // 图片分辨率之宽
unsigned int height; // 图片分辨率之高
unsigned int bpp; // 图片bpp
char *pData; // 指向图片有效数据存储的buf数据
}pic_info;
// 函数功能: 判断一个图片文件是不是png图片
// 函数参数: path是图片文件的pathname
// 返回值: 如果是png则返回0,不是则非0
int is_png(const 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;
// printf("%d %d %d %d\n", buf[0], buf[1], buf[2], buf[3]);
/* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
Return nonzero (true) if they match */
return(png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
}
/*
* 函数功能: 解码png图片,并将解码出来的RGB数据存储
* 函数参数: pPic,记录源png图片,解码出来的图片宽高、图片数据缓冲区等信息
* 返回值 : 成功解码则返回0,失败则返回-1
*/
int png_analyze(struct pic_info *pPic)
{
FILE *fp = NULL;
png_structp png_ptr;
png_infop info_ptr;
int color_type;
png_bytep* row_pointers;
unsigned long len = 0;
int pos = 0;
int i = 0, j = 0;
if ((fp = fopen(pPic->pathname, "rb")) == NULL)
{
fprintf(stderr, "can't open %s\n", pPic->pathname);
return -1;
}
// 第1步: 相关数据结构实例化
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (png_ptr == 0)
{
fclose(fp);
return -1;
}
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == 0)
{
png_destroy_read_struct(&png_ptr, 0, 0);
fclose(fp);
return -1;
}
// 第2步: 设置错误处理函数
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
fclose(fp);
return -1;
}
// 第3步: 将要解码的png图片的文件指针和png解码器绑定起来
png_init_io(png_ptr, fp);
// 第4步: 读取png图片信息
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA, 0);
// 第5步: 相关图片信息打印出来看一看
color_type = info_ptr->color_type;
debug("color_type = %d\n", color_type);
pPic->width = info_ptr->width;
pPic->height = info_ptr->height;
pPic->bpp = info_ptr->pixel_depth;
len = info_ptr->width * info_ptr->height * info_ptr->pixel_depth / 8;
debug("width = %u, height = %u, bpp = %u\n", pPic->width, pPic->height, pPic->bpp);
// 第6步: 读取真正的图像信息
row_pointers = png_get_rows(png_ptr,info_ptr);
// 只处理RGB24位真彩色图片,其他格式的图片不管
// 第7步: 图像数据移动到我们自己的buf中
if(color_type == PNG_COLOR_TYPE_RGB)
{
//memcpy(pPic->pData, row_pointers, len);
for(i=0; i<pPic->height; i++)
{
for(j=0; j<3*pPic->width; j+=3)
{
pPic->pData[pos++] = row_pointers[i][j+0];
pPic->pData[pos++] = row_pointers[i][j+1];
pPic->pData[pos++] = row_pointers[i][j+2];
}
}
}
// 第8步: 收尾处理
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
// close file
fclose(fp);
return 0;
}
7、参考资源
《朱友鹏——嵌入式核心课程》