百问FB显示开发图像处理 - PNG图像处理
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的编译过程:
- 解压并进入文件目录
tar xzf libpng-1.6.37.tar.gz
cd libpng-1.6.37/
- 交叉编译
./configure --prefix=/work/projects/libpng-1.6.37/tmp/ --host=arm-linux
make
make install
- 将编译出来的头文件和库文件拷贝到交叉编译器的相应目录下
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
- 将编译出来的头文件和库文件拷贝到开发板文件系统的相应目录下
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的使用步骤简单总结如下:
-
分配和初始化两个与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);
-
设置错误返回点
setjmp(png_jmpbuf(png_ptr));
当出现错误时,libpng将会自动调用返回到这个点。在这个点我们可以进行一些清理工作。如果在调用png_create_read_struct时没有设置自定义的错误处理函数,这一步是必须要做的。
-
指定源文件
png_init_io(png_ptr, fp);
参数1是步骤1中分配的png_ptr结构体,参数2是需要解析的PNG文件的文件句柄。
-
获取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中找到。
-
将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是存放图片数据的指针。
-
销毁内存
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
2.3.3 使用libpng把png文件转为rgb格式,在LCD上显示
代码清单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. }
相关文章:
百问FB显示开发图像处理 - PNG图像处理
2.3 PNG图像处理 2.3.1 PNG文件格式和libpng编译 跟JPEG文件格式一样,PNG也是一种使用了算法压缩后的图像格式,与JPEG不同,PNG使用从LZ77派生的无损数据压缩算法。对于PNG文件格式,也有相应的开源工具libpng。 libpng库可从…...
【JavaWeb后端学习笔记】MySQL多表查询(内连接、外连接、子查询)
MySQL 多表查询 1、连接查询1.1 内连接1.2 外连接 2、子查询2.1 标量子查询2.2 列子查询2.3 行子查询2.4 表子查询 3、多表查询案例 多表查询有两大类:连接查询和子查询。 连接查询又分为隐式/显式内连接和左/右外连接。 子查询又分为标量子查询、列子查询、行子查询…...

RocketMQ 过滤消息 基于tag过滤和SQL过滤
RocketMQ 过滤消息分为两种,一种tag过滤,另外一种是复杂的sql过滤。 tag过滤 首先创建producer然后启动,在这里创建了字符串的数组tags。字符串数组里面放置了多个字符串,然后去发送15条消息。 15条消息随着i的增长,…...

element-ui 基本样式的一些更改【持续更新】
1、 去除el-tabs的底部灰色横线 ::v-deep .el-tabs__nav-wrap::after {height: 0px;}2、el-table设置表头颜色 <el-table:data"tableData":header-cell-style"{background:#F7F8FA,color:#4E5869}"><el-table-columnlabel"序号"type&qu…...
element-ui radio和checkbox禁用时不置灰还是原来不禁用时的样式
把要紧用的内容加上一个class"notEdit-page" z注意要在style里面写不能加上scoped /*//checkBox自定义禁用样式*//*//checkBox自定义禁用样式*/ .notEdit-page.el-checkbox__input.is-disabled.is-checked.el-checkbox__inner::after {border-color: #fff; } .notEdi…...
第一部分:基础知识 6. 函数 --[MySQL轻松入门教程]
MySQL 提供了丰富的内置函数,涵盖了字符串处理、数值计算、日期时间操作、聚合分析以及控制流等多个方面。这些函数可以帮助用户更高效地进行数据查询和处理。 1.字符串函数 MySQL 提供了丰富的字符串函数来帮助用户处理和操作字符串数据。下面是一些常用的 MySQL…...
【蓝桥杯每日一题】扫雷
扫雷 知识点 2024-12-3 蓝桥杯每日一题 扫雷 dfs (bfs也是可行的) 题目大意 在一个二维平面上放置这N个炸雷,每个炸雷的信息有$(x_i,y_i,r_i) $,前两个是坐标信息,第三个是爆炸半径。然后会输入M个排雷火箭࿰…...

【算法】棋盘覆盖问题源代码及精简版
目录 一、题目 二、样例 三、示例代码 四、精简代码 五、总结 对于棋盘覆盖问题的解答和优化。 一、题目 输入格式: 第一行,一个整数n(棋盘n*n,n确保是2的幂次,n<64) 第二行,两个整数…...
Django的介绍
Django是一个高级的Python Web框架,它鼓励快速开发和干净、实用的设计。Django遵循MVC设计模式,即模型(Model)、视图(View)和控制器(Controller),并提供了一个即时可用的…...

【Spring工具插件】lombok使用和EditStarter插件
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 引入 一:lombok介绍 1:引入依赖 2:使用 3:原理 4&…...

掌控时间,成就更好的自己
在个人成长的道路上,时间管理是至关重要的一环。有效的时间管理能够让我们更加高效地完成任务,实现自己的目标,不断提升自我。 时间对每个人都是公平的,一天只有 24 小时。然而,为什么有些人能够在有限的时间里做出卓…...
Ruby On Rails 笔记2——表的基本知识
Active Record Basics — Ruby on Rails Guides Active Record Migrations — Ruby on Rails Guides 原文链接自取 1.Active Record是什么? Active Record是MVC模式中M的一部分,是负责展示数据和业务逻辑的一层,可以帮助你创建和使用Ruby…...

【AI系统】EfficientNet 系列
EfficientNet 系列 本文主要介绍 EffiicientNet 系列,在之前的文章中,一般都是单独增加图像分辨率或增加网络深度或单独增加网络的宽度,来提高网络的准确率。而在 EfficientNet 系列论文中,会介绍使用网络搜索技术(NAS)去同时探索…...
【Python小白|Python内置函数学习2】Python有哪些内置函数?不需要导入任何模块就可以直接使用的!现在用Python写代码的人还多吗?
【Python小白|Python内置函数学习2】Python有哪些内置函数?不需要导入任何模块就可以直接使用的!现在用Python写代码的人还多吗? 【Python小白|Python内置函数学习2】Python有哪些内置函数?不需要导入任何模块就可以直接使用的&a…...
蓝桥杯分治
P1226 【模板】快速幂 题目描述 给你三个整数 𝑎,𝑏,𝑝a,b,p,求 𝑎𝑏 mod 𝑝abmodp。 输入格式 输入只有一行三个整数,分别代表 𝑎,𝑏,𝑝a,b,p。…...

YOLOv8实战无人机视角目标检测
本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对无人机目标数据集进行训练和优化,该数据集包含丰富的无人机目标图像…...
三、【docker】docker和docker-compose的常用命令
文章目录 一、docker常用命令1、镜像管理2、容器管理3、容器监控和调试4、网络管理5、数据卷管理6、系统维护7、实用组合命令8、常用技巧二、docker-compose常用命令1、基本命令2、构建相关3、运行维护4、常用组合命令5、实用参数 一、docker常用命令 1、镜像管理 # 查看本地…...

Qt 2D绘图之五:图形视图框架的结构、坐标系统和框架间的事件处理与传播
参考文章链接: Qt 2D绘图之五:图形视图框架的结构和坐标系统 Qt 2D绘图之六:图形视图框架的事件处理与传播 图形视图框架的结构 在前面讲的基本绘图中,我们可以自己绘制各种图形,并且控制它们。但是,如果需要同时绘制很多个相同或不同的图形,并且要控制它们的移动、…...

基于SpringBoot+Vue的美妆购物网站
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...

MySQL之创建和管理表
目录 1. MySQL中的数据类型编辑编辑 2. 创建和管理数据库 方式1:创建数据库 方式2:创建数据库并指定字符集 方式3:判断数据库是否已经存在,不存在则创建数据库( 推荐 ) 总结 2.2 使用数据库 查看当…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...