Qt提供了四个处理图像数据的类: QImage、QPixmap、QBitmap 和QPicture.。
因为QImage是一个 QPaintDevice 子类,所以 QPainter也可以用来直接它,在QImage上使用QPainter时,绘制可以在当前GUI线程以外的其他线程中执行。
QImage类支持Format中描述的多种图像格式,包括单色、8位、32位和alpha混合图像。
QImage提供了一组函数用于获取图像信息,还可以支持对图像的变换操作。
QImage对象可以通过值传递,因为QImage类使用隐式数据共享。
QImage对象也可以进行流媒体处理和比较。
隐式数据共享是C++特性,用来提高资源使用效率并减少数据复制。
当这些类作为参数传递时,只传递一个指向数据的指针,只有当函数写入数据时才会被真正复制。
警告:不支持在具有 QImage::Format_Indexed8格式的QImage上进行绘制。
阅读和编写图像文件
QImage加载图像文件的方法:
- 文件可以在构建QImage对象时加载。
- 构建后使用 load()或loadFromData()函数加载。
QImage还提供了静态函数fromData(),从给定的数据构造一个QImage。
加载图像时,文件名可以引用磁盘上的实际文件,也可以引用应用程序的嵌入资源。(参阅Qt资源系统The Qt Resource System)
调用 save() 函数可以保存一个QImage对象。
可以通过QImage阅读器 QImageReader::supportedImageFormats() 和QImage写入器QImageWriter::supportedImageFormats() 函数获得QT所支持文件格式的完整列表,还可以添加插件以支持更多的文件格式。
Qt默认支持以下格式:
Format | Description | Qt's support |
---|---|---|
BMP | Windows Bitmap | Read/write |
GIF | Graphic Interchange Format (optional) | Read |
JPG | Joint Photographic Experts Group | Read/write |
JPEG | Joint Photographic Experts Group | Read/write |
PNG | Portable Network Graphics | Read/write |
PBM | Portable Bitmap | Read |
PGM | Portable Graymap | Read |
PPM | Portable Pixmap | Read/write |
XBM | X11 Bitmap | Read/write |
XPM | X11 Pixmap | Read/write |
图像信息
QImage提供了一组函数,可用于获取关于图像的各种信息:
Geometry 几何学 | 几何函数size(),width(),height(), dotsPerMeterX()和dotsPerMeterY() 提供了关于图像尺寸和宽高比的信息。 rect() 函数返回图像的封闭矩形。valid() 函数返回给定的坐标是否在这个矩形内。offset()返回图像相对于其它图像定位时打算被偏移的像素数量,这也可以通过 setOffset() 函数进行操作。 |
Colors 颜色 | 在单色和8位图像的情况下,颜色计数 colorCount()和颜色表 colorTable()函数提供了关于用于存储图像数据的颜色组件的信息: colorTable()函数返回图像的整个颜色表。要获得单个条目,请使用像素索引 pixelIndex() 函数检索给定的一对坐标的像素索引,然后使用 color()函数检索颜色。注意,如果您手动创建一个8位图像,您还必须在图像上设置一个有效的颜色表。 hasAlphaChannel()函数告诉图像的格式是否支持alpha通道。 allGray()和 isGrayscale()函数可以判断图像的颜色是否都是灰色的。 |
Text 文本 | |
Low-level information 底层信息 | depth()函数返回图像的位深。支持的深度为1(单色)、8、16、24和32位。 bitPlaneCount()函数告诉所使用的这些位的数量。有关更多信息,请参见 Image Formats 部分。 格式 format(),字节 bytesPerLine()和 sizeInBytes()函数提供关于存储在图像中的数据的低级信息。 cacheKey()函数返回一个唯一标识此QImage对象内容的数字。 |
像素操作
处理图像的像素的功能取决于图像格式。原因是单色图像和8位图像是基于索引的,并使用了一个颜色查找表,而32位图像直接存储ARGB值。
在32位图像的情况下,可以使用setPixel()函数用于将给定坐标下像素的颜色改变为指定为ARGB的任何其他颜色。要创建一个合适的 QRgb 值,请使用 qRgb()或 qRgba() 函数。
- 例如:
//构造QImage对象,宽高为3,格式为32位RGB(0xffRRGGBB)
QImage image(3, 3, QImage::Format_RGB32);
QRgb value;
value = qRgb(189, 149, 39); // 0xffbd9527
image.setPixel(1, 1, value);
value = qRgb(122, 163, 39); // 0xff7aa327
image.setPixel(0, 1, value);
image.setPixel(1, 0, value);
value = qRgb(237, 187, 51); // 0xffedba31
image.setPixel(2, 1, value);
在8位和单色图像的情况下,像素值只是图像颜色表中的一个索引。因此,setPixel()函数只能用于将给定坐标下的像素的颜色更改为图像的颜色表中的预定义颜色。它只能改变像素的索引值。要更改或添加到图像颜色表的颜色,需要使用setColor()。
颜色表中的一个条目是一个编码为QRgb的值。 可以使用 qRgb()或 qRgba() 函数来创建一个合适的QRgb值,用于setColor()函数。
- 例如:
QImage image(3, 3, QImage::Format_Indexed8); //使用8位索引格式存储
QRgb value;
value = qRgb(122, 163, 39); // 0xff7aa327
image.setColor(0, value);
value = qRgb(237, 187, 51); // 0xffedba31
image.setColor(1, value);
value = qRgb(189, 149, 39); // 0xffbd9527
image.setColor(2, value);
image.setPixel(0, 1, 0);
image.setPixel(1, 0, 0);
image.setPixel(1, 1, 2);
image.setPixel(2, 1, 1);
对于每个颜色通道超过8位的图像。方法 setPixelColor() 和 pixelColor() 都可以用来设置和获取QColor 的值。
QImage还提供了扫描线scanLine() 函数,该函数使用给定的索引返回指向扫描线上的像素数据的指针,以及位 bits() 函数返回指向第一个像素数据的指针(相当于扫描线(0))。
图像变换
QImage支持许多函数来创建一个新图像的转换版本: createAlphaMask() 函数从alppa缓冲区构建并返回一个1-bpp掩码,createHeuristicMask() 函数创建并返回一个1-bpp启发式掩码。后一个功能的工作原理是从其中一个角中选择一种颜色,然后从所有边缘开始去除该颜色的像素。
mirrored() 函数返回所需方向的镜像, scaled() 返回缩放到所需度量矩形的图像副本,rgbSwapped()函数从RGB图像构造一个BGR图像。
scaledToWidth() 和scaledToHeight() 函数返回图像的缩放副本。
转换transformed()函数返回图像的一个副本,该图像用给定的变换矩阵和变换模式进行转换。transformed() 返回包含原始图像的所有变换点的最小图像。静态矩阵 trueMatrix() 函数返回用于转换图像的实际矩阵。
还有一些功能可以用于更改原地图像的属性:
Function | Description |
---|---|
setDotsPerMeterX() | 设置在适合的像素数来定义长宽比。 |
setDotsPerMeterY() | |
fill() | 用给定的像素值填充整个图像。 |
invertPixels() | 使用给定的反转模式值反转图像中的所有像素值。 |
setColorTable() | 设置用于转换颜色索引的颜色表。仅对单色和8位格式。 |
setColorCount() | 请重新调整颜色表的大小。仅对单色和8位格式。 |