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

article/2025/10/19 5:44:35

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,会看到如下信息:

ConstantValueDescription
QImage::Format_Invalid0The image is invalid.
QImage::Format_Mono1The image is stored using 1-bit per pixel. Bytes are packed with the most significant bit (MSB) first.
QImage::Format_MonoLSB2The image is stored using 1-bit per pixel. Bytes are packed with the less significant bit (LSB) first.
QImage::Format_Indexed83The image is stored using 8-bit indexes into a colormap.
QImage::Format_RGB324The image is stored using a 32-bit RGB format (0xffRRGGBB).
QImage::Format_ARGB325The image is stored using a 32-bit ARGB format (0xAARRGGBB).
QImage::Format_ARGB32_Premultiplied6The image is stored using a premultiplied 32-bit ARGB format (0xAARRGGBB), i.e. the red, green, and blue channels are multiplied by the alpha component divided by 255. (If RR, GG, or BB has a higher value than the alpha channel, the results are undefined.) Certain operations (such as image composition using alpha blending) are faster using premultiplied ARGB32 than with plain ARGB32.
QImage::Format_RGB167The image is stored using a 16-bit RGB format (5-6-5).
QImage::Format_ARGB8565_Premultiplied8The image is stored using a premultiplied 24-bit ARGB format (8-5-6-5).
QImage::Format_RGB6669The image is stored using a 24-bit RGB format (6-6-6). The unused most significant bits is always zero.
QImage::Format_ARGB6666_Premultiplied10The image is stored using a premultiplied 24-bit ARGB format (6-6-6-6).
QImage::Format_RGB55511The image is stored using a 16-bit RGB format (5-5-5). The unused most significant bit is always zero.
QImage::Format_ARGB8555_Premultiplied12The image is stored using a premultiplied 24-bit ARGB format (8-5-5-5).
QImage::Format_RGB88813The image is stored using a 24-bit RGB format (8-8-8).
QImage::Format_RGB44414The image is stored using a 16-bit RGB format (4-4-4). The unused bits are always zero.
QImage::Format_ARGB4444_Premultiplied15The image is stored using a premultiplied 16-bit ARGB format (4-4-4-4).
QImage::Format_RGBX888816The image is stored using a 32-bit byte-ordered RGB(x) format (8-8-8-8). This is the same as the Format_RGBA8888 except alpha must always be 255. (added in Qt 5.2)
QImage::Format_RGBA888817The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8). Unlike ARGB32 this is a byte-ordered format, which means the 32bit encoding differs between big endian and little endian architectures, being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA. (added in Qt 5.2)
QImage::Format_RGBA8888_Premultiplied18The image is stored using a premultiplied 32-bit byte-ordered RGBA format (8-8-8-8). (added in Qt 5.2)
QImage::Format_BGR3019The image is stored using a 32-bit BGR format (x-10-10-10). (added in Qt 5.4)
QImage::Format_A2BGR30_Premultiplied20The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10). (added in Qt 5.4)
QImage::Format_RGB3021The image is stored using a 32-bit RGB format (x-10-10-10). (added in Qt 5.4)
QImage::Format_A2RGB30_Premultiplied22The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). (added in Qt 5.4)
QImage::Format_Alpha823The image is stored using an 8-bit alpha only format. (added in Qt 5.5)
QImage::Format_Grayscale824The image is stored using an 8-bit grayscale format. (added in Qt 5.5)
QImage::Format_Grayscale1628The image is stored using an 16-bit grayscale format. (added in Qt 5.13)
QImage::Format_RGBX6425The image is stored using a 64-bit halfword-ordered RGB(x) format (16-16-16-16). This is the same as the Format_RGBA64 except alpha must always be 65535. (added in Qt 5.12)
QImage::Format_RGBA6426The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12)
QImage::Format_RGBA64_Premultiplied27The image is stored using a premultiplied 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12)
QImage::Format_BGR88829The image is stored using a 24-bit BGR format. (added in Qt 5.14)

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

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

QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);//转成灰度图
image.setColorCount(256);				// 灰度级数256
for (int i = 0; i < 256; i++)
{image.setColor(i, qRgb(i, i, i));
}
uchar *pSrc = mat.data;					// 复制mat数据
for (int row = 0; row < mat.rows; row++)
{uchar *pDest = image.scanLine(row);memcpy(pDest, pSrc, mat.cols);pSrc += mat.step;
}
return image;

在这里插入图片描述

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zijkI9RV-1641819159212)(C:\Users\Censh77\AppData\Roaming\Typora\typora-user-images\image-20211230135344388.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MzuIb46T-1641819159213)(C:\Users\Censh77\AppData\Roaming\Typora\typora-user-images\image-20211230135912978.png)]

补充: α \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()函数

void QImage::setPixel(const QPoint &position, uint index_or_rgb)

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

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

2、pixel()函数

QRgb QImage::pixel(const QPoint &position) const

返回指定位置的像素颜色

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

3、scanLine()函数

uchar *QImage::scanLine(int i)

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

4、bits()函数

uchar *QImage::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()函数

const uchar *QImage::constScanLine(int i) const

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

6、constBit()函数

const uchar *QImage::constBits() const

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

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

7、setColor()函数

void QImage::setColor(int index, QRgb colorValue)

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

8、setColorCount()函数

void QImage::setColorCount(int colorCount)

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

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

9、colorCount()函数

int QImage::colorCount() const

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

10、color()函数

QRgb QImage::color(int i) const

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

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

11、setColorTable()函数

void QImage::setColorTable(const QVector<QRgb> colors)

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

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

12、colorTable()函数

QVector<QRgb> QImage::colorTable() const

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

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

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

QImage Qimg(imgWidth,imgHeight,QImage::Format_Indexed8);  
//QImage(int width, int height, QImage::Format format)
Qimg.setColorCount(256);				// 灰度级数256
for (int i = 0; i < 256; i++)
{Qimg.setColor(i, qRgb(i, i, i));
}
uchar tempData[imgWidth];
for (int i = 0; i < imgHeight; i++)
{for (int j = 0; j < imgWidth; j++){tempData[j] = Hidata[i*imgWidth + j]/16;//将第i+1行的数据复制给一维数组tempdata//Hidata[]为图像数据,事先将图像数据读入该一维数组中,该图像的高为imgWidth、宽为imgHeight}uchar *pDest = Qimg.scanLine(i);memcpy(pDest, tempData, imgWidth);
}
*qimgHi = Qimg;int pixelindexValue = qimgHi->pixelIndex(304,236);  //分析图像中点(304,236)处的坐标
qDebug() << "像素值索引pixelIndex()为:" << pixelindexValue << Qt::endl;QRgb mRgb = qimgHi->pixel(304,236);
QColor mColor = QColor(mRgb);qDebug() << "QColor,即pixel()为:" << mColor << Qt::endl;
qDebug() << mColor.red() << mColor.green() << mColor.blue() << Qt::endl;
qDebug() << "QRgb为:" << mRgb << Qt::endl;

运行结果如下:

像素值索引pixelIndex()为: 13 
QColor,即pixel()为: QColor(ARGB 1, 0.0509804, 0.0509804, 0.0509804)  //  13/255=0.0509804
13 13 13 
QRgb为: 4279045389 

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w4wF9VSw-1641819159213)(C:\Users\Censh77\AppData\Roaming\Typora\typora-user-images\image-20220110184529805.png)]

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

for (int i = 0; i < 256; i++)
{Qimg.setColor(i, qRgb(255-i, 255-i, 255-i));
}

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

像素值索引pixelIndex()为: 13 
QColor,即pixel()为: QColor(ARGB 1, 0.94902, 0.94902, 0.94902)   //  (255-13)/255=0.94902
242 242 242 
QRgb为: 4294111986 

对应的图像为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBdmreEK-1641819159214)(C:\Users\Censh77\AppData\Roaming\Typora\typora-user-images\image-20220110184838443.png)]

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

在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/FlMCCCVo.shtml

相关文章

J1939 协议

J1939 协议简介 J1939协议是基于CAN 2.0B所发展的出来的&#xff0c;基于CAN 的物理层。主要用于commercial vehicle的通信。J1939的主要目的是制定统一的上层application诊断的信息。 J1939的最大特点是定义了PGN&#xff08;Parameter Group Number). 大多数的PGN是8个字节…

SAE J1939学习笔记(三)

J1939故障代码种类 J1939 由几个不同的诊断信息&#xff1a; –诊断信息 1 - DM1 – 现行故障代码 –诊断信息 2 - DM2 – 非现行故障代码 –诊断信息 3 - DM3 – 清除非现行故障代码 通常地&#xff0c;用户会用 DM1 信息来读取现行故障码。 DM1 信息是 PGN 65226 or FECA h…

新功能发布—TSMaster如何实现J1939多帧报文收发

前言 众所周知&#xff0c;J1939协议是由美国汽车工程师协会&#xff08;SAE&#xff09;定义的一组标准。J1939标准用于卡车、公共汽车和移动液压等重型车辆。如今大多数车辆都通过CAN进行ECU通信。但是CAN总线仅仅是提供了通信的基础&#xff08;就像是电话&#xff09;&…

CAN协议 J1939

转自&#xff1a;http://blog.sina.com.cn/s/blog_bf97bd7e0102wl2y.html 这几天在公司看了SAE推行的 J1939标准&#xff08;SAE&#xff1a;美国汽车工程协会&#xff09;&#xff0c;这里整理下学习要点&#xff0c;主要包含以下几个协议&#xff1a; 物理层 SAE J1939-11…

J1939协议与CAN2.0对应关系图表

SAE J1939 消息帧格式定义与CAN 2.0B帧格式对应关系 J1939应用层协议详细描述了用于J1939网络的每个参数&#xff0c;包括其数据长度、数据类型、分辨率、范围及参考标签&#xff0c;并为每个参数分配了一个编号&#xff08;SPN&#xff09;。由于J1939协议是以协议数据单元&am…

Python实现CAN总线J1939报文接收、发送

前言 J1939协议是由美国汽车工程师协会&#xff08;SAE&#xff09; (SAE协会简介)定义的一组标准。J1939标准用于卡车、公共汽车和移动液压等重型车辆。在许多方面&#xff0c;J1939标准类似于旧版J1708和J1587标准&#xff0c;但J1939标准协议建立在CAN&#xff08;控制器区域…

J1939标准概述【小白入门】

文章目录 J1939标准概述&#xff1a;J1939/11物理层J1939/13板外诊断连接器J1939/21数据链路层J1939/31网络层J1939/71车辆应用层J1939/73应用层-诊断层J1939/81网络管理总结 J1939标准概述&#xff1a; J1939由下列子标准组成&#xff1a; J1939 – 串行控制和通信车辆网络…

J1939-21数据链路层多帧协议PDU解析

一、协议数据单元&#xff08;PDU&#xff09; P 是优先级&#xff0c;R 是保留位&#xff0c;DP 是数据页&#xff0c;PF 是PDU 格式&#xff0c;PS 是特定PDU&#xff0c;SA 是源地址 优先级&#xff08;P&#xff09;&#xff1a;这三位仅在总线传输中用来优化消息延迟&…

CAN总线的特点及J1939协议通信原理、内容和应用

众多国际知名汽车公司早在20世纪80年代就积极致力于汽车网络技术的研究及应用。迄今已有多种网络标准&#xff0c;如专门用于货车和客车上的SAE的J1939、德国大众的ABUS、博世的CAN、美国商用机器的AutoCAN、ISO的VAN、马自达的PALMNET等。 在我国的轿车中已基本具有电子控制和…

IPEmotion采集J1939协议信号

一 背景 由于商用车相对于乘用车更注重实用性&#xff0c;功能也较单一&#xff0c;且具有产量小的特点&#xff0c;因此在设计开发时需要进行约束&#xff0c;以更大程度实现软硬件的复用和成本的降低&#xff0c;在此需求下J1939协议便随之产生了。 J1939协议是由美国汽车工…

SAE J1939协议读取车辆故障码

基于SAE J1939协议的车辆&#xff0c;默认开启数据广播。当有故障码时&#xff0c;也会按照故障码的格式进行广播。 此处基于外设主动&#xff1a;读取故障码个数->读取故障码->故障码解析 这个步骤来讲&#xff0c;如果被动接收故障码广播&#xff0c;如下解析也适用。 …

车用总线技术 | J1939协议实用指南与J1939数据记录方案

“没错&#xff0c;这是一份SAE J1939协议的简单、实用指南。”—虹科 开篇&#xff1a;在这篇介绍中&#xff0c;我们介绍了J1939协议的基本知识&#xff0c;其中包括PGN和SPN。因为这是一篇偏向应用的简介&#xff0c;所以您还将会学习到如何通过DBC文件解码J1939数据、如何…

SAE J1939协议学习笔记

引用百度百科&#xff1a; SAE J1939&#xff08;以下简称J1939&#xff09;是美国汽车工程协会&#xff08;SAE&#xff09;的推荐标准&#xff0c;用于为中重型道路车辆上电子部件间的通讯提供标准的体系结构。它由“卡车与大型客车电气与电子委员会”&#xff08;Track &am…

J1939学习(二)

PDU 应用或网络层提供被同化为协议数据单元&#xff08;PDU&#xff09;的信息串。PDU提供了一个框架&#xff0c;用于组织对发送的每个CAN数据帧至关重要的信息。SAE J1939 PDU由七个字段组成&#xff1a;&#xff08;1&#xff09;P、&#xff08;2&#xff09;EDP、&#x…

CAN总线(J1939)速成指南【1】

本文转载在我的微信公众号&#xff1a;古德曼汽车工业。公众号文章都会知识星球、知乎进行转载&#xff0c;请有兴趣的朋友可以关注我的微信公众号 原文地址&#xff1a;CAN总线(J1939)速成指南【1】 很久以前当思想对CAN总线还一窍不通的时候&#xff0c;尝试百度搜索过非常…

J1939协议实用指南与J1939数据记录方案

“没错&#xff0c;这是一份SAE J1939协议的简单、实用指南。”—虹科 开篇&#xff1a;在这篇介绍中&#xff0c;我们介绍了J1939协议的基本知识&#xff0c;其中包括PGN和SPN。因为这是一篇偏向应用的简介&#xff0c;所以您还将会学习到如何通过DBC文件解码J1939数据、如何记…

车载通信——J1939故障码

一、诊断 UDS是统一诊断系统 冻结帧&#xff1a;出现故障码时&#xff0c;ECU存储故障码出现时的数据&#xff0c;就是冻结帧。 二、J1939故障诊断 SAE J1939应用层定义了12种诊断报文&#xff08;Diagnostic Message,DM&#xff09;、诊断故障码&#xff08;DTC&#xff0…

UDS,ISO14229,ISO15765,ISO15031,J1939车辆诊断协议入门系列

&#xff08;图片来源于网络&#xff09; 目录 摘要1. 基础概念1.1 诊断的概念1.2 诊断的目标1.3 诊断的实现1.4 诊断是分层的 2. 项目应用3. 协议栈开发 摘要 回想当年刚进去汽车行业&#xff0c;做新能源车的某个“ECU”&#xff0c;和客户沟通需求时&#xff0c;人家上来就…

J1939故障码诊断说明

1&#xff1a;1939整体协议说明 这里主要说明1939不同的协议&#xff0c;对应不同的网络分层 注意了&#xff0c;这里只进行文档解析说明&#xff0c;具体查看去搜素协议的关键字进行理解 2&#xff1a;DMx和FMI 说明 想知道每个代号的具体含义&#xff0c;可以去 saeJ1939…

J1939协议之通俗易懂----简介

J1939简介 J1939协议简介 J1939协议是由美国汽车工程师协会&#xff08;SAE&#xff09; (SAE协会简介)定义的一组标准。J1939标准用于卡车、公共汽车和移动液压等重型车辆。在许多方面&#xff0c;J1939标准类似于旧版J1708和J1587标准&#xff0c;但J1939标准协议建立在CAN…