当前位置: 首页 > news >正文

百问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的编译过程:

  1. 解压并进入文件目录
tar xzf libpng-1.6.37.tar.gz
cd libpng-1.6.37/
  1. 交叉编译
./configure --prefix=/work/projects/libpng-1.6.37/tmp/ --host=arm-linux
make
make install
  1. 将编译出来的头文件和库文件拷贝到交叉编译器的相应目录下
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. 将编译出来的头文件和库文件拷贝到开发板文件系统的相应目录下
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上显示

代码清单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文件格式一样&#xff0c;PNG也是一种使用了算法压缩后的图像格式&#xff0c;与JPEG不同&#xff0c;PNG使用从LZ77派生的无损数据压缩算法。对于PNG文件格式&#xff0c;也有相应的开源工具libpng。 libpng库可从…...

【JavaWeb后端学习笔记】MySQL多表查询(内连接、外连接、子查询)

MySQL 多表查询 1、连接查询1.1 内连接1.2 外连接 2、子查询2.1 标量子查询2.2 列子查询2.3 行子查询2.4 表子查询 3、多表查询案例 多表查询有两大类&#xff1a;连接查询和子查询。 连接查询又分为隐式/显式内连接和左/右外连接。 子查询又分为标量子查询、列子查询、行子查询…...

RocketMQ 过滤消息 基于tag过滤和SQL过滤

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

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 提供了丰富的内置函数&#xff0c;涵盖了字符串处理、数值计算、日期时间操作、聚合分析以及控制流等多个方面。这些函数可以帮助用户更高效地进行数据查询和处理。 1.字符串函数 MySQL 提供了丰富的字符串函数来帮助用户处理和操作字符串数据。下面是一些常用的 MySQL…...

【蓝桥杯每日一题】扫雷

扫雷 知识点 2024-12-3 蓝桥杯每日一题 扫雷 dfs &#xff08;bfs也是可行的&#xff09; 题目大意 在一个二维平面上放置这N个炸雷&#xff0c;每个炸雷的信息有$(x_i,y_i,r_i) $&#xff0c;前两个是坐标信息&#xff0c;第三个是爆炸半径。然后会输入M个排雷火箭&#xff0…...

【算法】棋盘覆盖问题源代码及精简版

目录 一、题目 二、样例 三、示例代码 四、精简代码 五、总结 对于棋盘覆盖问题的解答和优化。 一、题目 输入格式&#xff1a; 第一行&#xff0c;一个整数n&#xff08;棋盘n*n&#xff0c;n确保是2的幂次&#xff0c;n<64&#xff09; 第二行&#xff0c;两个整数…...

Django的介绍

Django是一个高级的Python Web框架&#xff0c;它鼓励快速开发和干净、实用的设计。Django遵循MVC设计模式&#xff0c;即模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#xff09;&#xff0c;并提供了一个即时可用的…...

【Spring工具插件】lombok使用和EditStarter插件

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 引入 一&#xff1a;lombok介绍 1&#xff1a;引入依赖 2&#xff1a;使用 3&#xff1a;原理 4&…...

掌控时间,成就更好的自己

在个人成长的道路上&#xff0c;时间管理是至关重要的一环。有效的时间管理能够让我们更加高效地完成任务&#xff0c;实现自己的目标&#xff0c;不断提升自我。 时间对每个人都是公平的&#xff0c;一天只有 24 小时。然而&#xff0c;为什么有些人能够在有限的时间里做出卓…...

Ruby On Rails 笔记2——表的基本知识

Active Record Basics — Ruby on Rails Guides Active Record Migrations — Ruby on Rails Guides 原文链接自取 1.Active Record是什么&#xff1f; Active Record是MVC模式中M的一部分&#xff0c;是负责展示数据和业务逻辑的一层&#xff0c;可以帮助你创建和使用Ruby…...

【AI系统】EfficientNet 系列

EfficientNet 系列 本文主要介绍 EffiicientNet 系列&#xff0c;在之前的文章中&#xff0c;一般都是单独增加图像分辨率或增加网络深度或单独增加网络的宽度&#xff0c;来提高网络的准确率。而在 EfficientNet 系列论文中&#xff0c;会介绍使用网络搜索技术(NAS)去同时探索…...

【Python小白|Python内置函数学习2】Python有哪些内置函数?不需要导入任何模块就可以直接使用的!现在用Python写代码的人还多吗?

【Python小白|Python内置函数学习2】Python有哪些内置函数&#xff1f;不需要导入任何模块就可以直接使用的&#xff01;现在用Python写代码的人还多吗&#xff1f; 【Python小白|Python内置函数学习2】Python有哪些内置函数&#xff1f;不需要导入任何模块就可以直接使用的&a…...

蓝桥杯分治

P1226 【模板】快速幂 题目描述 给你三个整数 &#x1d44e;,&#x1d44f;,&#x1d45d;a,b,p&#xff0c;求 &#x1d44e;&#x1d44f; mod &#x1d45d;abmodp。 输入格式 输入只有一行三个整数&#xff0c;分别代表 &#x1d44e;,&#x1d44f;,&#x1d45d;a,b,p。…...

YOLOv8实战无人机视角目标检测

本文采用YOLOv8作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。YOLOv8以其高效的实时检测能力&#xff0c;在多个目标检测任务中展现出卓越性能。本研究针对无人机目标数据集进行训练和优化&#xff0c;该数据集包含丰富的无人机目标图像…...

三、【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的美妆购物网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

MySQL之创建和管理表

目录 1. MySQL中的数据类型​编辑​编辑 2. 创建和管理数据库 方式1&#xff1a;创建数据库 方式2&#xff1a;创建数据库并指定字符集 方式3&#xff1a;判断数据库是否已经存在&#xff0c;不存在则创建数据库&#xff08; 推荐 &#xff09; 总结 2.2 使用数据库 查看当…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 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…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...