【小白课程】以openKylin看图软件为例,浅谈图片编解码库—FreeImage

news2024/11/19 15:13:49

看图软件是openKylin操作系统上一款开源的图像查看软件,支持对图片进行基本操作,如:缩放、翻转、详情查看、复制、打印、重命名等,同时还可以对图片进行裁剪、存储、标注和ocr(文字识别)。

图1 看图软件界面

作为图像查看软件,查看图片是其基本功能,也是最重要的功能。在看图软件V1.2.0版本中,新增了10种图片格式(exr,psd,jfi,jif,jng,wbmp,xbm,xpm,jp2,j2k)的查看和保存,这些格式在技术上都是通过FreeImage库实现的。下面将为大家着重介绍看图软件中所使用的图片编解码库—FreeImage。

1.看图软件图片编解码库介绍

openKylin系统中的看图软件目前共支持30种图片格式,分别为:bmp,jpeg,jpg,jpe,pnm,pgm,ppm,pbm,sr,ras,dib,png,apng,gif,webp,tga,svg,ico,tiff,tif,exr,psd,jfi,jif,jng,wbmp,xbm,xpm,jp2,j2k。

为支持上述图片格式,看图软件使用以下库进行图片编解码:opencv库,FreeImage库,apng库,gif库等。其中,一半格式的图片使用的是大家比较熟悉的opencv库编解码,个别格式的图片,如svg等有自己的相关库。除此之外都是使用的FreeImage库进行图片的读写。在使用过程中,我们发现,对上层应用来说FreeImage库快速便捷,易于使用。

2.FreeImage库介绍

FreeImage库是一款开源的,免费的和跨平台的图片编解码库。支持对20多种流行图形格式的处理,如BMP 、JPEG 、GIF 、PNG 、TIFF等。

使用FreeImage库时要安装libfreeimage-dev和libfreeimageplus-dev。同时,FreeImage库提供了很多获取位图信息的接口,具有快速、灵活、简单易用的特点。FreeImage库中的所有函数都是以FreeImage_开头,如图像文件的读写函数分别为FreeImage_Load 和FreeImage_Save ,并且和opencv之间相互转换也很简单,感兴趣的小伙伴可前往FreeImage官网查看更多详情。

3.使用FreeImage库加载图片

看图软件在加载或操作一张图片的整个过程都是以cv::mat矩阵来存储图片的。打开一张图片时,看图软件使用FreeImage库加载图片的完整流程如下所示:

1. 获取图片真实格式;

2. 判断图片是否支持FreeImage读入;

3. FreeImage加载图片,获得FIBITMAP;

4. 将FIBITMAP转换为cv::mat;

5. 从内存中删除libfreeimage载入的图片,防止内存泄漏。

3.1 获取图片真实格式

在操作图片时,图片后缀可能是.xbm,.sr等,但这并不代表图片是xbm或sr格式,此时需要先通过库函数来获取图片的真实格式。

// 用库获取文件格式,path是图片的路径。     QByteArray temp_path;     temp_path.append(path.toUtf8());     FREE_IMAGE_FORMAT format = FreeImage_GetFileType(temp_path.data());

FreeImage_GetFileType:由文件头拿到文件类型。参数:图片路径。

这个函数的返回值是FREE_IMAGE_FORMAT。可以从下图看到,返回值也可能是FIF_UNKNOWMN。

图2 图片类型

如果从库函数中解析出来的文件格式为FIF_UNKNOWMN,我们会从文件数据的角度,通过判断文件头,再次解析图片格式,提升拿到正确文件格式的成功率。

QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {      return FIF_UNKNOWN;
}
const QByteArray data = file.read(64);
/* Check bmp file */
if (data.startsWith("BM")) {    s return FIF_BMP;
}
//path为图片路径

3.2 判断是否支持读入

在拿到文件类型后,加载图片之前,我们还需要做一个工作:判断该格式是否可以被FreeImage库读取。其中FreeImage_FIFSupportsReading用来判断是否支持该位图类型的读操作。

3.3 加载图片

假设我们已经拿到图片的正确格式,且该格式可以被FreeImage库读取。则调用库函数FreeImage_Load 加载位图,返回值为FIBITMAP。FIBITMAP数据结构保存着位图信息和像素数据,是FreeImage的核心。

3.4 将FIBITMAP转换成mat

在看图软件中,读写图片的整个流程的数据都是以cv::mat矩阵进行传递的。之所以使用cv::mat是为了之后能够对看图软件现有的功能进行扩展,尤其是opencv提供的AI方向。

图3 看图软件结构

因此,在拿到FreeImage返回的FIBITMAP后,我们需要将它转换为cv::mat。

FIBITMAP转换成cv::mat时,首先要看构造一个图片的mat矩阵都需要什么参数。

Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);//行数rows,列数cols,类型type,指向用户数据的指针data,每行占据的字节数。

所以,接下来我们的任务就是,从FIBITMAP拿到需要的所有参数。

1. int rows, int cols

对于行数和列数,FreeImage有函数可以直接调用,得到行列。

FIBITMAP *dib;
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);

2. inttype

对于type,需要稍微做一下处理。FreeImage库提供了查看图片深度和数据类型的方法。

int bpp = FreeImage_GetBPP(src);//图片的深度
FREE_IMAGE_TYPE fit = FreeImage_GetImageType(src);//返回位图的数据类型

拿到FreeImage的类型的枚举值后,一一对应转为cv::mat的数据类型即可。

图4 数据类型

3. void* data

指向用户数据的指针data。

库中同样有可以直接调用的函数。

FreeImage_GetBits(FIBITMAP *dib):返回一个指向位图的数据位的指针

4. size_t step

step 每行占据的字节数

FreeImage_GetPitch(FIBITMAP *dib):返回位深度或线宽度(又叫做扫描宽度)。是以字节为单位返回对齐到下一个32位字节边界的位图宽度。

FIBITMAP *dib;
int step = FreeImage_GetPitch(dib);

3.5内存释放

FIBITMAP *dib;
FreeImage_Unload(dib);//从内存中删除载入图片,防止内存泄漏

除了FreeImage库外,目前还有许多优秀的图片编解码库,openKylin看图软件后续会适配更多的图片库来支持更多格式,并利用opencv的特性来扩展一些特色功能。各位小伙伴敬请期待吧!

openKylin(开放麒麟)社区旨在以“共创”为核心,在开源、自愿、平等、协作的基础上,通过开源、开放的方式与企业构建合作伙伴生态体系,共同打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态繁荣发展。

社区首批理事成员单位包括麒麟软件、普华基础软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、元心科技、中国电科32所、技德系统、北京麟卓、先进操作系统创新中心等13家产业同仁和行业机构。

来源:openKylin

审核:openKylin

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/194753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信通院联合偶数科技等企业发布《云原生湖仓一体白皮书》

2023年1月9日,云原生产业联盟在今年年会上重磅发布了《云原生湖仓一体白皮书》。该白皮书由中国信通院牵头,偶数科技、中国人寿、中信建投、中国联通等单位共同编写。 本次白皮书从云原生湖仓的发展历程、技术方案、生态现状、实践案例等方面进行了全面深…

Linux C 捕捉 Ctrl+C 的SIGINT信号

kill -l可以看每个数字对应的信号信号值9和15的区别:kill命令默认是-15,代表的信号为SIGTERM,在结束此进程之前,允许此进程做一些清理工作kill -9会直接杀死目标进程,不给其机会做清理工作按键盘的 CtrlC时&#xff0c…

测试高薪必备

测试人员由于工作原因要经常检查数据库的数据是否正确,这个时候就需要频繁使用多表查询。 在多表查询中,应用最多的就是内连接,其次就是子查询。 为什么子查询是在工作中应用也有这么广泛的应用呢?原因在于子查询非常方便…

macOS下使用vscode+xdebug调试php

手动安装xdebug1、浏览器访问https://xdebug.org/wizard2、在本地终端输入php -i 命令,将输出的内容复制到指南中的输入框中并提交分析3、分析完后会给出分析概览,然后根据下面提示步骤进行手动安装即可第5步中的phpize 命令位置:/usr/local/Cellar/php7…

神经网络基础与原理

7.1 神经网络基础与原理 学习目标 目标 了解感知机结构、作用以及优缺点了解tensorflow playground的使用说明感知机与神经网络的联系说明神经网络的组成说明神经网络的分类原理说明softmax回归说明交叉熵损失应用 无 7.1.1 神经网络 人工神经网络( Artificial N…

Oracle数据库卸载安装

卸载oracle步骤:1.首先关掉所有oracle的相关服务,然后找到oracle的卸载程序Universal Installer:2.卸载,删除所有应用然后继续点击卸载产品,然后点击展开全部,将主目录以外的所有应用全部卸载掉&#xff0c…

【C语言】C语言中a<b<c与a<bb<c的区别你注意到了嘛?

问题导入   今天碰到了一个if(a<b<c)逻辑一直成立&#xff0c;无论a,b,c三者的值如何&#xff0c;输出结果一直一样。&#x1f605;&#x1f605;&#x1f605;大家可以看看下图&#xff1a; 逻辑运算测试1 不过讲实话&#xff0c;在实际写代码过成中&#xff0c;小编一…

【数据结构基础】树 - 哈夫曼树(Huffman Tree)

哈夫曼又称最优二叉树, 是一种带权路径长度最短的二叉树。(注意带权路径WPL是指叶子节点&#xff0c;很多网上的文章有误导) 哈夫曼树相关名词先看一棵哈夫曼树: (哈夫曼树推理是通过叶子节点&#xff0c;所以理解的时候需要忽略非叶子节点&#xff0c;很多文章在这点上有误导)…

CHAPTER 14 Swarm

Swarm14.1 Swarm简介14.2 Swarm vs K8s14.3 基本概念1. Swarm集群2.节点3.服务4.任务5.服务的外部访问14.4 使用Swarm1.创建集群(init)2.查看集群信息(info)3.加入集群(join)4.使用集群服务(service)1. 创建服务(service create)2. 查看服务(service ls)3. 扩缩服务(service sc…

力扣:至少是其他数字两倍的最大数(详解)

前言&#xff1a;本期是关于至少是其他数字两倍的最大数的详解&#xff0c;内容包括四大模块&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读&#xff0c;今天你c了吗&#xff1f; 题目&#xff1a; 给你一个整数数组 nums &#xff0c;其中总…

如何对企业网站进行优化?(网站怎样优化seo)

探析企业网站优化怎么做才有效果&#xff1f; 在互联网营销时代&#xff0c;搜索引擎一直是推广流量的重要途径&#xff0c;越来越多的企业已经涉足搜索引擎优化行业&#xff0c;众多企业做网站优化是为了网站提升企业知名度和流量&#xff0c;争取以更低成本做更高转化、更快…

公务机包机|公务飞行包机攻略解答

公务机是一种在行政事务和商业活动中用作交通工具的飞行&#xff0c;也被称为行政机或商用飞机。公务机包机程序简单&#xff0c;不仅可以享受不一致的尊崇服务&#xff0c;而且可以避免巨额投资和日常管理的繁琐事务。    公务机是指在行政事务和商业活动中用作交通工具的飞…

最重要的定理:隐函数定理

多元函数变限积分求导问题

整理网上拷贝的文档格式-去掉代码前的序号

1、整理换行 第一步&#xff0c;将所有的纯换行的地方替换为空&#xff08;也就是删除他们&#xff09;&#xff0c;我这里是将选择题的各选项之间的换行替换为两个制表符&#xff08;两个Tab键&#xff09;&#xff1a; 执行这一步的时候注意将通配符的选项勾选上&#xff0c…

利用Python计算离散点构成曲线的曲率

目录一、实现原理1.1、计算点到直线的距离——海伦公式参考链接计算曲率就是为了求这段弧长对应的半径&#xff0c;也就是说&#xff0c;我们把曲线看成圆的弧长就行&#xff0c;那么问题就简单了。一、实现原理 1.1、计算点到直线的距离——海伦公式 如下图所示&#xff0c;…

【MyBatis】第四篇:浅聊resultType

前提 学生对象不会变如下&#xff1a; package com.xzd.domain;public class Student {Integer sid;String sname;int sage;String ssex;public Student() {}public Student(Integer sid, String sname, int sage, String ssex) {this.sid sid;this.sname sname;this.sage …

如何把图片转换成word文档?说一个转换途径

我们时常需要将图片上的文字资料归纳整理下来&#xff0c;转成Word文档的形式会方便很多&#xff0c;下面给大家介绍一下如何把图片转换成word文档&#xff0c;有多种方式&#xff0c;咱们自由选择。方式一、直接添加图片转换成Word这种方式非常简单&#xff0c;我们打开Word或…

校园IP网络广播系统方案

北京恒星科通发布于2023-2-2 一、校园IP网络广播系统概述 校园I P网络广播系统&#xff0c;是构建在当前广泛使用的TCP/IP通讯网络基础上的新一代交互式公共广播系统。系统采用分布式服务器架构&#xff0c;容量可以根据需要不断扩展&#xff0c;可以在局域网或者广域网内运行…

21-死锁的解除及银行家算法

预防死锁 不允许死锁的发生 静态策略:预防思索 破坏互斥条件 如果能把互斥使用的资源改造为允许共享使用,则系统不会进入死锁状态,比如SPOOLing技术,操作系统可以采用SPOOLing技术把独占设备在逻辑上改造为共享设备。 使用了SPOOLing技术后,在各进程看来,自己对打印机资源的…

2023年java面试常考知识点(12题)

一. 接⼝与抽象类区别 1、⼀个类声明可否既是abstract的,⼜是final的? 不能,这两个修式符⽭盾&#xff08;abstract就是要被继承&#xff09; 2、抽象类不⼀定包含抽象⽅法 3、有抽象⽅法,则⼀定是抽象类 4、抽象类不能被实例化&#xff0c;⼀般⽤作基类使⽤&#xff1b; a. 类…