Qt QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)

打开Qt帮助文档,会看到有关于QImage的描述如下:The QImage class provides a hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device。即QImage类是设备无关的图像,可以进行像素级操作,也可以被用作绘图设备,因为QImage继承于QPaintDevice。

Format:

打开enum QImage::Format,会看到如下信息:

注意:Drawing into a QImage with QImage::Format_Indexed8 is not supported,即对于Format_Indexed8这种格式是不支持绘图的。

只分析几个常用的格式,Format_Indexed8

补充两个函数: setPixel( )和setColor( )

对于32位图,每一个像素拥有一个自己的rgb值(RGB、ARGB、premultiplied ARGB),可以使用setPixel( )函数更改任一坐标的ARGB值,例如:

而对于基于索引的单色图和8位图像,需要使用颜色查找表(color table)来操作像素。8-bit图像的每一个像素的值是color。此类图像的像素值只是图像颜色表中的索引。因此,setPixel( )函数只能用于将给定坐标下的像素颜色更改为图像颜色表中的预定义颜色,即它只能更改像素的索引值。要更改图像的颜色表或者向其中添加颜色,可以使用setColor( )函数。例如:

补充:α \alphaα通道:

阿尔法通道(α Channel或Alpha Channel)是指一张图片的透明和半透明度。例如:一个使用每个像素16比特存储的位图,对于图形中的每一个像素而言,可能以5个比特表示红色,5个比特表示绿色,5个比特表示蓝色,最后一个比特是阿尔法。在这种情况下,它要么表示透明要么不是,因为阿尔法比特只有0或1两种不同表示的可能性。又如一个使用32个比特存储的位图,每8个比特表示红绿蓝,和阿尔法通道。在这种情况下,就不光可以表示透明还是不透明,阿尔法通道还可以表示256级的半透明度,因为阿尔法通道有8个比特可以有256种不同的数据表示可能性。

以上说的ARGB值,是关于四通道图片的,其中A代表的就是Alpha值,有时也写作RGBA。例如:以上color table中的0xffbd9527(十六进制)表示不透明的颜色,oxff是255,bd是189,95是149,27是39。即(0xffRRGGBB)。

1、setPixel()函数

将给定位置的像素索引或颜色设置为索引或rgb。
如果图像的格式为单色或调色板,则给定的索引或rgb值必须是图像颜色表中的索引,否则该参数必须是QRgb值。
如果position不是图像中的有效坐标对,或者如果index_或_rgb>=colorCount()(对于单色和调色板图像),则结果未定义。
Warning:由于在中调用了内部detach()函数,因此此函数的开销较大;如果性能是一个问题,我们建议使用scanLine()或bits()直接访问像素数据。

官方也不推荐以上函数来访问QImage像素,因为效率极低,开销较大。

2、pixel()函数

返回指定位置的像素颜色

同样有Warning: This function is expensive when used for massive pixel manipulations. Use constBits() or constScanLine() when many pixels needs to be read.

3、scanLine()函数

返回索引为i的扫描线处的像素数据指针。第一条扫描线位于索引0处。

4、bits()函数

返回指向第一个像素数据的指针。这相当于scanLine(0)。

Note that QImage uses implicit data sharing. This function performs a deep copy of the shared pixel data, thus ensuring that this QImage is the only one using the current return value.

Implicit Sharing:

Qt中的许多C++类使用隐式数据共享来最大化资源使用和最小化复制。隐式共享类在作为参数传递时既安全又高效,因为只传递指向数据的指针,并且仅当函数写入数据时(即,写入时复制)才会复制数据。在使用=操作符的时候浅复制。

5、constScanLine()函数

返回索引为i的扫描线处的像素数据指针。第一条扫描线位于索引0处。

6、constBit()函数

返回指向第一个像素数据的指针。

请注意,QImage使用隐式数据共享,但此函数不执行共享像素数据的深度复制,因为返回的数据是常量。

7、setColor()函数

将颜色表中给定索引处的颜色设置为给定的colorValue,colorValue是一个ARGB四元组。如果索引超出颜色表的当前大小,则会使用 setColorCount()函数扩展。

8、setColorCount()函数

调整颜色表的大小以包含colorCount个条目,如果颜色表是可扩展的,所有额外颜色将设置为透明(即qRgba(0,0,0,0))。

使用图像时,颜色表必须足够大,以包含图像中所有像素/索引值的条目,否则结果将无法定义。

9、colorCount()函数

返回图像颜色表的大小。注意,对于32 bpp图像,colorCount()返回0,因为这些图像不使用颜色表,而是将像素值编码为ARGB四元组。

10、color()函数

返回索引i处颜色表中的颜色。第一种颜色位于索引0处。

图像颜色表中的颜色指定为ARGB四元组(QRgb)。使用qAlpha()、qRed()、qGreen()和qBlue()函数获取颜色值组件。

11、setColorTable()函数

将用于将颜色索引转换为QRgb值的颜色表设置为指定的颜色。

使用图像时,颜色表必须足够大,以包含图像中所有像素/索引值的条目,否则结果将无法定义。

12、colorTable()函数

返回图像颜色表中包含的颜色列表,如果图像没有颜色表,则返回空列表

有的时候只看注释也不能完全搞懂函数的意思,举一些实例吧

以上部分函数的使用举例(主要代码): 直接建立一个Indexed8格式的QImage,并读入数据

运行结果如下:

此时对应的图像如下:(工作原因,本次所展示图像均为部分图像)

可以看出pixelIndex()返回当前位置的索引值,而索引值13正好在ColorTable中对应的QRgb也是(13,13,13),而4279045389对应的十六进制为: ff0d0d0d。为了证明pixelIndex()返回的就是索引,可以将上述程序做一变化,如下:

此时的程序输出结果如下,pixelIndex()依然返回当前位置的索引值,但是该索引对应的颜色变成了(242,242,242)

对应的图像为:

用不同的QImage格式,即使用Qimg.convertToFormat(QImage::Format_Grayscale8)语句,得到不同格式的QImage,并取图像中16个点的pixelIndex和pixel矩阵进行分析,得到列表如下,可见不同格式对图像还是有一定影响的,不展开分析了。

Original: https://www.cnblogs.com/ybqjymy/p/16520316.html
Author: 一杯清酒邀明月
Title: Qt QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/546561/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 嵌入式软件开发之程序架构设计-任务调度

    1 前言 在嵌入式MCU软件开发过程中,程序任务调度架构的搭建尤为重要,直接关系到该程序能支持多少功能(随着功能越多系统响应能力越弱,好的任务调度架构能够在保持相同的系统响应能力前…

    技术杂谈 2023年7月25日
    077
  • 解决Ubuntu19安装openjdk8后与openjfx不兼容

    小淘气放假了,孩子在上幼儿园的小朋友,报班也不能太变态嘛, 还是让他自己娱乐的时间多一点,但是现在在家的娱乐就是看电视,听说电视看多了越看越傻,就想方设法的给他找一点娱乐活动,把我…

    技术杂谈 2023年7月23日
    080
  • Ajax是什么

    Ajax(Asynchronous JavaScript and XML,异步JavaScript和XML)技术主要完毕 页面的局部刷新,通过Ajax技术能够使之前的应用程序在每次…

    技术杂谈 2023年5月31日
    084
  • 设计模式 20 观察者模式

    观察者模式(Observer Pattern)属于 行为型模式 在 Java 中,一个对象的状态发生改变,就可能会影响到其他的对象,与之相关的对象可能也会联动的进行改变。 比如监听…

    技术杂谈 2023年7月25日
    070
  • pip常用命令

    pip常用命令: bundle,创建包含多&am…

    技术杂谈 2023年7月11日
    065
  • COLA 4.x和DDD项目实践精粹

    在《COLA 4.x架构入门和项目实践》专栏基础之上,对项目开发实践进行了提炼和总结;同时,针对其中的一些知识点进行扩展和延伸。 专栏介绍 领域驱动设计(Domain Driven…

    技术杂谈 2023年6月1日
    087
  • 日常踩坑_添加了@Transactional注解后,事务不生效

    故事梗概 事情是这样的,在使用Jpa的saveAll方法的时候,发现saveAll方法会进行先查询后保存的操作,但我只想要保存,不想要查询关于saveAll的重写 可以这样用 @P…

    技术杂谈 2023年7月25日
    091
  • ntpd dead but pid file exists

    ntpd -gnqd ntpd 4.2.2p1@1.1570-o Fri Jul 22 18:07:53 UTC 2011 (1) addto_syslog: precision …

    技术杂谈 2023年5月30日
    084
  • 通俗易懂讲枚举

    枚举使用关键字 enum 进行定义,每个元素都是一个实例,如下,FOO 和 BAR 都是一个 EnumClazz 实例。 public enum EnumClazz { FOO, …

    技术杂谈 2023年7月25日
    090
  • 如何使能TF-A的调试开关?

    答: 编译时指定DEBUG=1,示例如下:$ make .. DEBUG=1 .. (..表示其它参数) Original: https://www.cnblogs.com/dak…

    技术杂谈 2023年5月31日
    071
  • 使用pdf.js快速实现pdf查看器

    最近准备对项目中的一个在线PDF查看器组件进行重构下,这个组件最开始用的浏览器内置的pdf查看的功能实现的,在使用中,遇到了很多不大容易解决的问题: 不同的浏览器样式不一样 禁止默…

    技术杂谈 2023年5月31日
    0105
  • 线程池的极简用法——内置线程池multiprocessing

    大家好,今天博主来分享一个线程池的小捷径——内置线程池的使用方法 一、背景 说道多线程,对变成层有了解的小伙伴一定不陌生,虽然不知道是什么但是也会从各大网站、面试分享等途径听说过。…

    技术杂谈 2023年7月11日
    061
  • 为vscode开发一款svn右键菜单扩展

    在我平时的工作中会经常用到svn blame这个命令,但是vscode现有的svn扩展普遍都不能自定义右键菜单。 所以我产生一个想法:自己动手为vscode开发一款svn的扩展来定…

    技术杂谈 2023年6月1日
    097
  • chromium 绘制 paint 与 合成

    关于paint的文档有两个。一个是下面的平台相关的 Paint artifact,即绘制指令执行完的生成品;另一个是core内核生成paint。 这个目录包含 display li…

    技术杂谈 2023年5月31日
    090
  • Netty源码分析之ByteBuf(二)—内存分配器ByteBufAllocator

    Netty中的内存分配是基于ByteBufAllocator这个接口实现的,通过对它的具体实现,可以用来分配我们之前描述过的任意类型的BytebBuf实例;我们先看一下ByteBu…

    技术杂谈 2023年7月25日
    071
  • 55.不舍

    dsfds posted @2022-09-28 08:31 随遇而安== 阅读(5 ) 评论() 编辑 Original: https://www.cnblogs.com/55z…

    技术杂谈 2023年6月21日
    095
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球