首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >百问FB显示开发图像处理 - PNG图像处理

百问FB显示开发图像处理 - PNG图像处理

作者头像
阿志小管家
发布于 2024-12-03 00:24:24
发布于 2024-12-03 00:24:24
38000
代码可运行
举报
运行总次数:0
代码可运行

2.3 PNG图像处理

2.3.1 PNG文件格式和libpng编译

​ 跟JPEG文件格式一样,PNG也是一种使用了算法压缩后的图像格式,与JPEG不同,PNG使用从LZ77派生的无损数据压缩算法。对于PNG文件格式,也有相应的开源工具libpng。

libpng库可从官网上下载最新的源代码:

http://www.libpng.org/pub/png/libpng.html

在使用libpng之前,我们先要交叉编译libpng的库文件和头文件并存到开发板的文件系统中。以下是libpng的编译过程:

  1. 解压并进入文件目录
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tar xzf libpng-1.6.37.tar.gz
cd libpng-1.6.37/
  1. 交叉编译
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./configure --prefix=/work/projects/libpng-1.6.37/tmp/ --host=arm-linux
make
make install
  1. 将编译出来的头文件和库文件拷贝到交叉编译器的相应目录下
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cd /work/projects/libpng-1.6.37/tmp/include
cp * /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
cd /work/projects/libpng-1.6.37/tmp/lib
cp *so* -d /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib
  1. 将编译出来的头文件和库文件拷贝到开发板文件系统的相应目录下
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cd /work/projects/libpng-1.6.37/tmp/lib
cp *.so* /work/nfs_root/fs_mini_mdev_new/lib/ -d
2.3.2 libpng接口函数的解析和使用

libpng的使用方法可以参考解压包中的使用说明libpng-manual.txt和例程example.c。libjpeg的使用步骤简单总结如下:

  1. 分配和初始化两个与libpng相关的结构体png_ptr,info_ptr A. png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); ​ 参数2,3,4分别是用户自定义的错误处理函数,若无,则填NULL。

​ B. info_ptr = png_create_info_struct(png_ptr);

  1. 设置错误返回点 setjmp(png_jmpbuf(png_ptr)); 当出现错误时,libpng将会自动调用返回到这个点。在这个点我们可以进行一些清理工作。如果在调用png_create_read_struct时没有设置自定义的错误处理函数,这一步是必须要做的。
  2. 指定源文件 png_init_io(png_ptr, fp); 参数1是步骤1中分配的png_ptr结构体,参数2是需要解析的PNG文件的文件句柄。
  3. 获取PNG图像的信息 A. 解析图片数据信息 png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); 该函数会把所有的图片数据解码到info_ptr数据结构中。至于转化为什么格式,由参数png_transforms决定,它是一个整型参数,可以使用libpng库中定义的宏进行传参。这个参数相关的宏有很多,具体的可以参考库中的相关文件的解析。 B.查询图像信息

此外,我们还可以通过png_get_image_width,png_get_image_height,png_get_color_type等函数获得png图像的宽度,高度,颜色类型等信息,更多的图像信息获取函数可以在文件pngget.c中找到。

  1. 将info_ptr中的图像数据读取出来 有两种读取PNG图像信息的方法: A. 一次性把所有的数据读入内存 png_read_image(png_ptr, row_pointers); 参数1是步骤1中分配的png_ptr,参数2是存放图片数据的指针。 B. 也可以逐行读取 row_pointers = png_get_rows(png_ptr, info_ptr); 参数1和参数2分别是步骤1中分配的png_ptr, info_ptr,返回值是每行数据的首地址。 参数1是步骤1中分配的png_ptr,参数2是存放图片数据的指针。
  2. 销毁内存 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
2.3.3 使用libpng把png文件转为rgb格式,在LCD上显示
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
代码清单2.3
1.	/********************************************************************** 
2.	 * 函数名称: IsnotPng 
3.	 * 功能描述:判断是否为PNG文件 
4.	 * 输入参数: ppFp - 文件句柄指针 
5.	                    strFileName - 文件名 
6.	 * 返 回 值:0 - 是PNG格式 其他-不是PNG格式 
7.	 ***********************************************************************/  
8.	int IsnotPng(FILE **ppFp, const char *strFileName)   
9.	{  
10.	    char strCheckHeader[8];   
11.	    *ppFp= fopen(strFileName, "rb");  
12.	    if (*ppFp== NULL) {  
13.	        return -1;  
14.	    }  
15.	    /* 读取PNG文件前8个字节,使用库函数png_sig_cmp即可判断是否为PNG格式 */  
16.	    if (fread(strCheckHeader, 1, 8, *ppFp) != 8)   
17.	        return -1;  
18.	    return png_sig_cmp(strCheckHeader, 0, 8);   
19.	  
20.	}  
21.	  
22.	/********************************************************************** 
23.	 * 函数名称: DecodePng2Rgb 
24.	 * 功能描述:把PNG文件解析为RGB888格式 
25.	 * 输入参数: ptData - 内含文件信息 
26.	 *                             strFileName - 文件名 
27.	 * 输出参数:PT_PictureData->pucRgbData - 内含rgb数据 
28.	 * 返 回 值:0 - 成功 其他-失败 
29.	 ***********************************************************************/  
30.	static int DecodePng2Rgb(const char *strFileName, PT_PictureData ptData)   
31.	{      
32.	    int i, j;  
33.	    int iPos = 0;  
34.	    png_bytepp pucPngData;   
35.	    /* 0.判断该文件是否为PNG格式 */  
36.	    if (IsnotPng(&ptData->ptFp, strFileName)) {  
37.	        printf("file is not png ...\n");  
38.	        return -1;  
39.	    }   
40.	  
41.	    /* 1.分配和初始化两个与libpng相关的结构体png_ptr,info_ptr */  
42.	    ptData->ptPngStrPoint  = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);   
43.	    ptData->ptPngInfoPoint= png_create_info_struct(ptData->ptPngStrPoint);  
44.	  
45.	    /* 2.设置错误的返回点 */  
46.	    setjmp(png_jmpbuf(ptData->ptPngStrPoint));  
47.	    rewind(ptData->ptFp); //等价fseek(fp, 0, SEEK_SET);  
48.	  
49.	    /* 3.指定源文件 */  
50.	    png_init_io(ptData->ptPngStrPoint, ptData->ptFp);  
51.	  
52.	    /* 4.获取PNG图像数据信息和通道数,宽度,高度等  
53.	      * 使用PNG_TRANSFORM_EXPAND宏做参数的作用是根据通道数的不同, 
54.	      * 将PNG图像转换为BGR888或ABGR8888格式*/  
55.	    png_read_png(ptData->ptPngStrPoint, ptData->ptPngInfoPoint, PNG_TRANSFORM_EXPAND, 0);   
56.	    ptData->iChannels    = png_get_channels(ptData->ptPngStrPoint, ptData->ptPngInfoPoint);   
57.	    ptData->iWidth    = png_get_image_width(ptData->ptPngStrPoint, ptData->ptPngInfoPoint);  
58.	    ptData->iHeight  = png_get_image_height(ptData->ptPngStrPoint, ptData->ptPngInfoPoint);  
59.	  
60.	  
61.	    /* 5.将info_ptr中的图像数据读取出来 */  
62.	    pucPngData = png_get_rows(ptData->ptPngStrPoint, ptData->ptPngInfoPoint); //也可以分别每一行获取png_get_rowbytes();  
63.	    if (ptData->iChannels == 4) { //判断是24位还是32位  
64.	        ptData->iRawSize= ptData->iWidth * ptData->iHeight*4; //申请内存先计算空间    
65.	        ptData->pucRawData= (unsigned char*)malloc(ptData->iRawSize);  
66.	        if (NULL == ptData->pucRawData) {  
67.	            printf("malloc rgba faile ...\n");  
68.	            png_destroy_read_struct(&ptData->ptPngStrPoint, &ptData->ptPngInfoPoint, 0);  
69.	            fclose(ptData->ptFp);  
70.	            return -1;  
71.	        }  
72.	        /* 从pucPngData里读出实际的RGBA数据出来  
73.	         * 源数据为ABGR格式*/  
74.	        for (i = 0; i < ptData->iHeight; i++)   
75.	            for (j = 0; j < ptData->iWidth * 4; j += 4) {  
76.	                    ptData->pucRawData[iPos++] = pucPngData[i][j + 3];  
77.	                    ptData->pucRawData[iPos++] = pucPngData[i][j + 2];  
78.	                    ptData->pucRawData[iPos++] = pucPngData[i][j + 1];  
79.	                    ptData->pucRawData[iPos++] = pucPngData[i][j + 0];  
80.	                }  
81.	  
82.	        /* 将得到的RGBA转换为RGB888格式 */  
83.	        if(RgbaToRgb(ptData)!=0)  
84.	            return -1;  
85.	  
86.	    }  
87.	    else if (ptData->iChannels == 3 ) { //判断颜色深度是24位还是32位  
88.	        ptData->iRgbSize= ptData->iWidth * ptData->iHeight*3; //申请内存先计算空间    
89.	        ptData->pucRgbData = (unsigned char*)malloc(ptData->iRgbSize);  
90.	        if (NULL == ptData->pucRgbData) {  
91.	            printf("malloc rgba faile ...\n");  
92.	            png_destroy_read_struct(&ptData->ptPngStrPoint, &ptData->ptPngInfoPoint, 0);  
93.	            fclose(ptData->ptFp);  
94.	            return -1;  
95.	        }  
96.	        /* 从pucPngData里读出实际的RGB数据 
97.	          * 源数据为BGR格式*/  
98.	        for (i = 0; i < ptData->iHeight; i ++) {  
99.	            for (j = 0; j < ptData->iWidth*3; j += 3) {  
100.	                ptData->pucRgbData[iPos++] = pucPngData[i][j+2];  
101.	                ptData->pucRgbData[iPos++] = pucPngData[i][j+1];  
102.	                ptData->pucRgbData[iPos++] = pucPngData[i][j+0];  
103.	            }  
104.	        }  
105.	        ptData->iBpp = 24;//转化之后的格式为RGB888格式  
106.	    }   
107.	    else return -1;   
108.	  
109.	      
110.	    /* 6:销毁内存 */  
111.	    png_destroy_read_struct(&ptData->ptPngStrPoint, &ptData->ptPngInfoPoint, 0);  
112.	    fclose(ptData->ptFp);  
113.	  
114.	  
115.	    return 0;  
116.	}   
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux应用开发【第二章】图像处理应用开发
​ 前言:所有的图像文件,都是一种二进制格式文件,每一个图像文件,都可以通过解析文件中的每一组二进制数的含义来获得文件中的各种信息,如图像高度,宽度,像素位数等等。只是不同的文件格式所代表的二进制数含义不一样罢了。我们可以通过UltraEdit软件打开图像文件并查看里面的二进制数排列。
韦东山
2021/12/15
1.2K0
Linux应用开发【第二章】图像处理应用开发
百问FB显示开发图像处理 - JPEG图像处理
​ JPEG的后缀名为.jpg的图像文件。对于图像内容和信息相同的JPEG文件和BMP文件,JPEG格式的文件要比BMP格式的文件小得多,这是因为JPEG文件是经过JPEG压缩算法后得到的一种文件格式。
阿志小管家
2024/11/29
3300
百问FB显示开发图像处理 - BMP图像处理
​ 前言:所有的图像文件,都是一种二进制格式文件,每一个图像文件,都可以通过解析文件中的每一组二进制数的含义来获得文件中的各种信息,如图像高度,宽度,像素位数等等。只是不同的文件格式所代表的二进制数含义不一样罢了。我们可以通过UltraEdit软件打开图像文件并查看里面的二进制数排列。
阿志小管家
2024/11/29
3160
百问FB显示开发图像处理 - BMP图像处理
【玩转Arm-2D】零基础Arm-2D API绘图入门无忧
Arm-2D是Arm公司为Cortex-M处理器平台量身打造的一款2D图形处理方案。针对已有的经典Cortex-M内核,诸如Cortex-M0/M0+/M3/M4/M7/M33等,Arm-2D提供了经过优化了的软件加速库——虽然在资源丰富的环境下,Arm-2D在这些传统处理器上无法与市面上各类GUI在同等条件下拉开性能差距,但在大部分GUI都无法覆盖的小资源处理器上,Arm-2D却提供了以极其低廉的手段实现智能手机级别GUI的可能性。当然更不用说在最新问世的Cortex-M55处理器上,借助Helium技术的加持,Arm-2D可以提供相较传统方案4倍以上的加速能力。
GorgonMeducer 傻孩子
2023/09/06
1.2K0
【玩转Arm-2D】零基础Arm-2D API绘图入门无忧
图像库 libpng 编译与实践
在之前的文章中介绍了 stb_image 图像库,还顺带提到了 libpng 和 libjpeg ,这篇文章就是介绍如何在 Android 平台上用 CMake 编译 libpng 动态库以及 libpng 使用实践。
音视频开发进阶
2019/07/17
2K0
【例说Arm-2D界面设计】从不规则图标的显示说起
Arm-2D是Arm公司为Cortex-M处理器平台量身打造的一款2D图形处理方案。针对已有的经典Cortex-M内核,诸如Cortex-M0/M0+/M3/M4/M7/M33等,Arm-2D提供了经过优化了的软件加速库——虽然在资源丰富的环境下,Arm-2D在这些传统处理器上无法与市面上各类GUI在同等条件下拉开性能差距,但在大部分GUI都无法覆盖的小资源处理器上,Arm-2D却提供了以极其低廉的手段实现智能手机级别GUI的可能性。当然更不用说在最新问世的Cortex-M55处理器上,借助Helium技术的加持,Arm-2D可以提供相较传统方案4倍以上的加速能力。
GorgonMeducer 傻孩子
2021/10/21
1K0
【例说Arm-2D界面设计】从不规则图标的显示说起
Linux应用开发-LCD显示BMP图片
BMP是一种与硬件设备无关的图像文件格式,是Windows环境中交换与图有关的数据的一种标准,在Windows环境中运行的图形图像软件都支持BMP图像格式。BMP格式的图片存放的就是原始的RGB数据,一般没有做压缩,也就是图片的画质是最原始的,也导致BMP图片占用的内存非常大。现在常用的jpg、jpeg格式都是压缩格式,保存的时候通过算法编码压缩,显示的时候再解压成RGB数据渲染显示。
DS小龙哥
2022/05/11
4.5K0
Linux应用开发-LCD显示BMP图片
【Arm-2D】不整活儿玩啥GUI?
之前,我们说过Arm-2D虽然本意是在底层默默的为各类商用和开源GUI软件协议栈提供加速服务,但考虑到在资源受限的深度嵌入式系统环境下,仍然有一大批贫下中农不辞辛劳的在 32~64K Flash、4~32K SRAM的单片机里“螺蛳壳里做道场”——“妄图染指”一般只有高端处理器才能触碰的“华丽”图形界面,Arm-2D也为这些享受不起哪怕是起码LVGL恩惠的资源难民,提供了一系列享受浪漫的机会。
GorgonMeducer 傻孩子
2021/05/27
1.1K0
Linux小项目-数码相册设计
这是基于Linux系统开发板设计一个小项目-数码相册,在LCD屏上可以显示完成常见的图片显示,翻页、旋转、缩放等功能。
DS小龙哥
2022/05/11
1.5K0
Linux小项目-数码相册设计
Android5.0 Recovery源代码分析与定制---recovery UI相关(二)
这段代码都做了哪些事情呢?这些recovery初始化图形显示最开始的部分:(1)调用了miniui中的gr_init初始化显示图形相关的步骤,因为recovery是基于framebuffer机制显示的。
杨源鑫
2019/07/04
1.5K0
Android5.0 Recovery源代码分析与定制---recovery UI相关(二)
Linux小项目-倒车影像功能设计
倒车影像已经是现在汽车的标配功能了,基本很多车出厂都是360全景影像,倒车影像又称泊车辅助系统,这篇文章就采用Linux开发板完成一个倒车影像的功能。
DS小龙哥
2022/05/11
2.5K0
Linux小项目-倒车影像功能设计
【例说Arm-2D界面设计】做剪影风也太简单了8!
在上一篇文章《【例说Arm-2D界面设计】从不规则图标的显示说起》的最后,我们展示了如何使用Arm-2D在RGB565环境下显示带有Alpha通道的图片的(比如png格式的图片)方法:
GorgonMeducer 傻孩子
2021/11/02
8100
【例说Arm-2D界面设计】做剪影风也太简单了8!
【玩转Arm-2D】为什么说“得蒙版者得GUI”
在上一篇文章《【玩转Arm-2D】零基础Arm-2D API绘图入门无忧》的最后,我们展示了如何使用Arm-2D在RGB565环境下显示带有Alpha通道的图片的(比如png格式的图片)方法:
GorgonMeducer 傻孩子
2023/09/06
4250
【玩转Arm-2D】为什么说“得蒙版者得GUI”
LibJPEG库使用_通过LibJPEG将RGB数据保存为JPG图片存储到磁盘
LibJPEG库是一个广泛使用的开源C库,用于处理JPEG图像的压缩和解压缩。该库由独立JPEG小组(Independent JPEG Group, IJG)开发,提供了功能强大的API,用于创建和读取JPEG文件。LibJPEG库支持JPEG的所有常见功能,包括高质量的压缩、解压缩、图像处理、颜色空间转换等。采用DCT(离散余弦变换)算法实现了高效的图像压缩,同时支持各种图像质量的调整。LibJPEG的灵活性和性能使其成为图像处理应用中的标准工具,被广泛应用于图像编辑软件、图像查看器、图像传输等多个领域。该库跨平台兼容,支持Windows、Linux、macOS等操作系统,开发者可以轻松将其集成到不同的平台和应用中。LibJPEG库还具有良好的文档支持,提供详细的编程指南和示例代码,帮助开发者快速上手和实现复杂的图像处理功能。由于其开源性质和广泛的应用,LibJPEG在业界享有很高的声誉,成为许多图像处理项目的首选库。
DS小龙哥
2025/05/27
2080
LibJPEG库使用_通过LibJPEG将RGB数据保存为JPG图片存储到磁盘
linux安装lib包_linux生成静态库
前几天手里的智能锁项目 , 收到产品的建议(命令)说 , 就是人脸识别成功的时候 , 不要只显示摄像头捕捉到的图像 , 要弄个酷炫一点的背景, 背景里图片中间有个圆圈, 人脸就放到圆圈里也就是类似这样。。
全栈程序员站长
2022/11/15
6.6K0
linux安装lib包_linux生成静态库
百问FB显示开发图像处理 - 图像调整
图像缩放算法有很多种,这里参考网友"lantianyu520"所著的"图像缩放算法"。
阿志小管家
2024/12/03
3110
百问FB显示开发图像处理 - 图像调整
Linux应用开发-libjpeg库交叉编译与使用
在开发板上如果想要显示jpeg格式的图片,必须用到libjpeg库,不可能自己去编写jpg的解码代码。
DS小龙哥
2022/05/09
4.2K0
Linux应用开发-libjpeg库交叉编译与使用
Linux下采集摄像头的图像再保存为JPG图片存放到本地(YUYV转JPG)
操作系统:ubuntu18.04 X64位 和 嵌入式Linux操作(ARM)
DS小龙哥
2022/01/12
4.7K0
Linux下采集摄像头的图像再保存为JPG图片存放到本地(YUYV转JPG)
Windows下使用QT+OpenCV完成人脸检测(获取摄像头的数据进行检测)_解决内存释放问题
上一版本的QT+OpenCV例子在这里:https://blog.csdn.net/xiaolong1126626497/article/details/105295367
DS小龙哥
2022/01/12
2K0
Windows下使用QT+OpenCV完成人脸检测(获取摄像头的数据进行检测)_解决内存释放问题
全志 Tina Linux LCD显示屏调试指南 支持MIPI DSI RGB LVDS I8080 SPI等接口,开发板支持百问网T113 D1-H哪吒 DongshanPI-D1s V853
素时钟不超过180MHz 都支持。或者两个串行RGB 接口,串行RGB 的最高分辨率最大不超过800*480@60
韦东山
2022/12/28
5.9K0
全志 Tina Linux LCD显示屏调试指南 支持MIPI DSI RGB LVDS I8080 SPI等接口,开发板支持百问网T113 D1-H哪吒 DongshanPI-D1s V853
推荐阅读
相关推荐
Linux应用开发【第二章】图像处理应用开发
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档