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

article/2025/10/19 5:33:49

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

 

 本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

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

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

 1 QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);//转成灰度图2 image.setColorCount(256);                // 灰度级数2563 for (int i = 0; i < 256; i++)4 {5     image.setColor(i, qRgb(i, i, i));6 }7 uchar *pSrc = mat.data;                    // 复制mat数据8 for (int row = 0; row < mat.rows; row++)9 {
10     uchar *pDest = image.scanLine(row);
11     memcpy(pDest, pSrc, mat.cols);
12     pSrc += mat.step;
13 }
14 return image;

补充两个函数: 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()函数

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,并读入数据

 1 QImage Qimg(imgWidth,imgHeight,QImage::Format_Indexed8);  2 //QImage(int width, int height, QImage::Format format)3 Qimg.setColorCount(256);                // 灰度级数2564 for (int i = 0; i < 256; i++)5 {6     Qimg.setColor(i, qRgb(i, i, i));7 }8 uchar tempData[imgWidth];9 for (int i = 0; i < imgHeight; i++)
10 {
11     for (int j = 0; j < imgWidth; j++)
12     {
13         tempData[j] = Hidata[i*imgWidth + j]/16;//将第i+1行的数据复制给一维数组tempdata
14         //Hidata[]为图像数据,事先将图像数据读入该一维数组中,该图像的高为imgWidth、宽为imgHeight
15     }
16     uchar *pDest = Qimg.scanLine(i);
17     memcpy(pDest, tempData, imgWidth);
18 }
19 *qimgHi = Qimg;
20 
21 int pixelindexValue = qimgHi->pixelIndex(304,236);  //分析图像中点(304,236)处的坐标
22 qDebug() << "像素值索引pixelIndex()为:" << pixelindexValue << Qt::endl;
23 
24 QRgb mRgb = qimgHi->pixel(304,236);
25 QColor mColor = QColor(mRgb);
26 
27 qDebug() << "QColor,即pixel()为:" << mColor << Qt::endl;
28 qDebug() << mColor.red() << mColor.green() << mColor.blue() << Qt::endl;
29 qDebug() << "QRgb为:" << mRgb << Qt::endl;

运行结果如下:

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

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

 

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

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

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

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

对应的图像为:

 

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

 本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓


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

相关文章

PyQt5-QImage、QPixmap、Opencv与QLabel、Matplotlib的互动

文章目录 前言一、转换1.1 Opencv_to_QPixmap1.2 QImage_to_QPixmap1.3 QPixmap_to_Opencv1.4 QImage_to_Opencv1.5 Opencv_to_QImage 二、实战案例2.1 案例1-图像旋转 总结 前言 早期进行图像旋转用的笨方法是&#xff1a; cv2.imread()读取图像numpy旋转图像将旋转后的图像保…

QImage 图片分割、保存

QImage 图片分割、保存 简介 之前一直只用Qt做图片显示&#xff0c;这次突发奇想想用Qt做做图像相关的&#xff0c;就尝试了一下图片切割&#xff0c;保存。 QImage介绍 QImage类为Qt提供的一个支持图像算法处理的类库&#xff0c;可以精确到像素及单位。在我理解不是提供了…

QImage类

QImage类提供了一个硬件无关的图像表示方法&#xff0c;该图像可以逐像素被访问和用于画图设备。 Qt提供了QImage、QPixmap、QBitmap和QPicture四种图像操作类。QImage类主要用于I/O和直接逐像素访问、操作&#xff1b;QPixmap主要用于在屏幕中显示图像&#xff1b;QBitmap是一…

Qt使用QImage保存成JPG(PNG)图像到本地

一、QImage类简介 QImage提供了一个与硬件无关的图像表示方法&#xff0c;允许直接访问像素数据&#xff0c;可用作绘图设备。QImage类支持QImage::Format、enum描述的多种图像格式。包括8-bit, 32-bit 和alpha混合图像QImage 提供很多可以用于获取图像信息和进行图像变换的函…

QImage

一、描述 QImage 类提供了一种独立于硬件的图像表示&#xff0c;允许直接访问像素数据&#xff0c;并且可以用作绘图设备。 QImage 是为 I/O 和直接像素访问和操作而设计和优化的&#xff0c; 因为 QImage 是 QPaintDevice 的子类&#xff0c;所以 QPainter 可用于直接在图像…

图像处理 QImage

在Qt中有四种处理图像的方法&#xff1a; QImage &#xff1a;使用I/O &#xff0c;可以对像素进行处理QPixmap&#xff1a;主要用在屏幕的显示QBitmap&#xff1a; QPixmap的子类&#xff0c;处理颜色深度&#xff0c;只能显示黑白两种颜色&#xff0c;用于遮罩QPicture&…

QImage的用法

QImage提供了几种加载图像文件的方法&#xff1a; &#xff08;1&#xff09;构造QImage对象 Image myImage1 QImage(filename); 根据文件名打开图像 支持的图片格式是&#xff1a; &#xff08;2&#xff09;QImage(uchar *data, int width, int height, Format format …) 用…

QImage使用说明

详细描述 QImage类提供独立于硬件的图像表示&#xff0c;允许直接访问像素数据&#xff0c;并可用作绘制设备。 Qt提供了四个用于处理图像数据的类&#xff1a;QImage、QPixmap、QBitmap和QPicture。QImage针对I/O、直接像素访问和操作进行了设计和优化&#xff0c;而QPixmap…

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

QImage类&#xff08;QImage类型转换、QImage类函数及QImage像素操作&#xff09; 打开Qt帮助文档&#xff0c;会看到有关于QImage的描述如下&#xff1a;The QImage class provides a hardware-independent image representation that allows direct access to the pixel dat…

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;如下解析也适用。 …