QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)
QImage類(lèi)(QImage類(lèi)型轉(zhuǎn)換、QImage類(lèi)函數(shù)及QImage像素操作)
打開(kāi)Qt幫助文檔,會(huì)看到有關(guān)于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類(lèi)是設(shè)備無(wú)關(guān)的圖像,可以進(jìn)行像素級(jí)操作,也可以被用作繪圖設(shè)備,因?yàn)镼Image繼承于QPaintDevice。
Format:
打開(kāi)enum QImage::Format,會(huì)看到如下信息:
| QImage::Format_Invalid | 0 | The image is invalid. |
| QImage::Format_Mono | 1 | The image is stored using 1-bit per pixel. Bytes are packed with the most significant bit (MSB) first. |
| QImage::Format_MonoLSB | 2 | The image is stored using 1-bit per pixel. Bytes are packed with the less significant bit (LSB) first. |
| QImage::Format_Indexed8 | 3 | The image is stored using 8-bit indexes into a colormap. |
| QImage::Format_RGB32 | 4 | The image is stored using a 32-bit RGB format (0xffRRGGBB). |
| QImage::Format_ARGB32 | 5 | The image is stored using a 32-bit ARGB format (0xAARRGGBB). |
| QImage::Format_ARGB32_Premultiplied | 6 | The 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_RGB16 | 7 | The image is stored using a 16-bit RGB format (5-6-5). |
| QImage::Format_ARGB8565_Premultiplied | 8 | The image is stored using a premultiplied 24-bit ARGB format (8-5-6-5). |
| QImage::Format_RGB666 | 9 | The image is stored using a 24-bit RGB format (6-6-6). The unused most significant bits is always zero. |
| QImage::Format_ARGB6666_Premultiplied | 10 | The image is stored using a premultiplied 24-bit ARGB format (6-6-6-6). |
| QImage::Format_RGB555 | 11 | The image is stored using a 16-bit RGB format (5-5-5). The unused most significant bit is always zero. |
| QImage::Format_ARGB8555_Premultiplied | 12 | The image is stored using a premultiplied 24-bit ARGB format (8-5-5-5). |
| QImage::Format_RGB888 | 13 | The image is stored using a 24-bit RGB format (8-8-8). |
| QImage::Format_RGB444 | 14 | The image is stored using a 16-bit RGB format (4-4-4). The unused bits are always zero. |
| QImage::Format_ARGB4444_Premultiplied | 15 | The image is stored using a premultiplied 16-bit ARGB format (4-4-4-4). |
| QImage::Format_RGBX8888 | 16 | The 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_RGBA8888 | 17 | The 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_Premultiplied | 18 | The image is stored using a premultiplied 32-bit byte-ordered RGBA format (8-8-8-8). (added in Qt 5.2) |
| QImage::Format_BGR30 | 19 | The image is stored using a 32-bit BGR format (x-10-10-10). (added in Qt 5.4) |
| QImage::Format_A2BGR30_Premultiplied | 20 | The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10). (added in Qt 5.4) |
| QImage::Format_RGB30 | 21 | The image is stored using a 32-bit RGB format (x-10-10-10). (added in Qt 5.4) |
| QImage::Format_A2RGB30_Premultiplied | 22 | The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). (added in Qt 5.4) |
| QImage::Format_Alpha8 | 23 | The image is stored using an 8-bit alpha only format. (added in Qt 5.5) |
| QImage::Format_Grayscale8 | 24 | The image is stored using an 8-bit grayscale format. (added in Qt 5.5) |
| QImage::Format_Grayscale16 | 28 | The image is stored using an 16-bit grayscale format. (added in Qt 5.13) |
| QImage::Format_RGBX64 | 25 | The 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_RGBA64 | 26 | The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12) |
| QImage::Format_RGBA64_Premultiplied | 27 | The image is stored using a premultiplied 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12) |
| QImage::Format_BGR888 | 29 | The 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,即對(duì)于Format_Indexed8這種格式是不支持繪圖的。
只分析幾個(gè)常用的格式,Format_Indexed8
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);//轉(zhuǎn)成灰度圖 image.setColorCount(256); // 灰度級(jí)數(shù)256 for (int i = 0; i < 256; i++) {image.setColor(i, qRgb(i, i, i)); } uchar *pSrc = mat.data; // 復(fù)制mat數(shù)據(jù) for (int row = 0; row < mat.rows; row++) {uchar *pDest = image.scanLine(row);memcpy(pDest, pSrc, mat.cols);pSrc += mat.step; } return image;補(bǔ)充兩個(gè)函數(shù): setPixel( )和setColor( )
對(duì)于32位圖,每一個(gè)像素?fù)碛幸粋€(gè)自己的rgb值(RGB、ARGB、premultiplied ARGB),可以使用setPixel( )函數(shù)更改任一坐標(biāo)的ARGB值,例如:
而對(duì)于基于索引的單色圖和8位圖像,需要使用顏色查找表(color table)來(lái)操作像素。8-bit圖像的每一個(gè)像素的值是color。此類(lèi)圖像的像素值只是圖像顏色表中的索引。因此,setPixel( )函數(shù)只能用于將給定坐標(biāo)下的像素顏色更改為圖像顏色表中的預(yù)定義顏色,即它只能更改像素的索引值。要更改圖像的顏色表或者向其中添加顏色,可以使用setColor( )函數(shù)。例如:
補(bǔ)充:α\alphaα通道:
阿爾法通道(α Channel或Alpha Channel)是指一張圖片的透明和半透明度。例如:一個(gè)使用每個(gè)像素16比特存儲(chǔ)的位圖,對(duì)于圖形中的每一個(gè)像素而言,可能以5個(gè)比特表示紅色,5個(gè)比特表示綠色,5個(gè)比特表示藍(lán)色,最后一個(gè)比特是阿爾法。在這種情況下,它要么表示透明要么不是,因?yàn)榘柗ū忍刂挥?或1兩種不同表示的可能性。又如一個(gè)使用32個(gè)比特存儲(chǔ)的位圖,每8個(gè)比特表示紅綠藍(lán),和阿爾法通道。在這種情況下,就不光可以表示透明還是不透明,阿爾法通道還可以表示256級(jí)的半透明度,因?yàn)榘柗ㄍǖ烙?個(gè)比特可以有256種不同的數(shù)據(jù)表示可能性。
以上說(shuō)的ARGB值,是關(guān)于四通道圖片的,其中A代表的就是Alpha值,有時(shí)也寫(xiě)作RGBA。例如:以上color table中的0xffbd9527(十六進(jìn)制)表示不透明的顏色,oxff是255,bd是189,95是149,27是39。即(0xffRRGGBB)。
1、setPixel()函數(shù)
void QImage::setPixel(const QPoint &position, uint index_or_rgb)將給定位置的像素索引或顏色設(shè)置為索引或rgb。
如果圖像的格式為單色或調(diào)色板,則給定的索引或rgb值必須是圖像顏色表中的索引,否則該參數(shù)必須是QRgb值。
如果position不是圖像中的有效坐標(biāo)對(duì),或者如果index_或_rgb>=colorCount()(對(duì)于單色和調(diào)色板圖像),則結(jié)果未定義。
Warning:由于在中調(diào)用了內(nèi)部detach()函數(shù),因此此函數(shù)的開(kāi)銷(xiāo)較大;如果性能是一個(gè)問(wèn)題,我們建議使用**scanLine()或bits()**直接訪問(wèn)像素?cái)?shù)據(jù)。
官方也不推薦以上函數(shù)來(lái)訪問(wèn)QImage像素,因?yàn)樾蕵O低,開(kāi)銷(xiāo)較大。
2、pixel()函數(shù)
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()函數(shù)
uchar *QImage::scanLine(int i)返回索引為i的掃描線處的像素?cái)?shù)據(jù)指針。第一條掃描線位于索引0處。
4、bits()函數(shù)
uchar *QImage::bits()返回指向第一個(gè)像素?cái)?shù)據(jù)的指針。這相當(dāng)于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++類(lèi)使用隱式數(shù)據(jù)共享來(lái)最大化資源使用和最小化復(fù)制。隱式共享類(lèi)在作為參數(shù)傳遞時(shí)既安全又高效,因?yàn)橹粋鬟f指向數(shù)據(jù)的指針,并且僅當(dāng)函數(shù)寫(xiě)入數(shù)據(jù)時(shí)(即,寫(xiě)入時(shí)復(fù)制)才會(huì)復(fù)制數(shù)據(jù)。在使用=操作符的時(shí)候淺復(fù)制。
5、constScanLine()函數(shù)
const uchar *QImage::constScanLine(int i) const返回索引為i的掃描線處的像素?cái)?shù)據(jù)指針。第一條掃描線位于索引0處。
6、constBit()函數(shù)
const uchar *QImage::constBits() const返回指向第一個(gè)像素?cái)?shù)據(jù)的指針。
請(qǐng)注意,QImage使用隱式數(shù)據(jù)共享,但此函數(shù)不執(zhí)行共享像素?cái)?shù)據(jù)的深度復(fù)制,因?yàn)榉祷氐臄?shù)據(jù)是常量。
7、setColor()函數(shù)
void QImage::setColor(int index, QRgb colorValue)將顏色表中給定索引處的顏色設(shè)置為給定的colorValue,colorValue是一個(gè)ARGB四元組。如果索引超出顏色表的當(dāng)前大小,則會(huì)使用 setColorCount()函數(shù)擴(kuò)展。
8、setColorCount()函數(shù)
void QImage::setColorCount(int colorCount)調(diào)整顏色表的大小以包含colorCount個(gè)條目,如果顏色表是可擴(kuò)展的,所有額外顏色將設(shè)置為透明(即qRgba(0,0,0,0))。
使用圖像時(shí),顏色表必須足夠大,以包含圖像中所有像素/索引值的條目,否則結(jié)果將無(wú)法定義。
9、colorCount()函數(shù)
int QImage::colorCount() const返回圖像顏色表的大小。注意,對(duì)于32 bpp圖像,colorCount()返回0,因?yàn)檫@些圖像不使用顏色表,而是將像素值編碼為ARGB四元組。
10、color()函數(shù)
QRgb QImage::color(int i) const返回索引i處顏色表中的顏色。第一種顏色位于索引0處。
圖像顏色表中的顏色指定為ARGB四元組(QRgb)。使用qAlpha()、qRed()、qGreen()和qBlue()函數(shù)獲取顏色值組件。
11、setColorTable()函數(shù)
void QImage::setColorTable(const QVector<QRgb> colors)將用于將顏色索引轉(zhuǎn)換為QRgb值的顏色表設(shè)置為指定的顏色。
使用圖像時(shí),顏色表必須足夠大,以包含圖像中所有像素/索引值的條目,否則結(jié)果將無(wú)法定義。
12、colorTable()函數(shù)
QVector<QRgb> QImage::colorTable() const返回圖像顏色表中包含的顏色列表,如果圖像沒(méi)有顏色表,則返回空列表
有的時(shí)候只看注釋也不能完全搞懂函數(shù)的意思,舉一些實(shí)例吧
以上部分函數(shù)的使用舉例(主要代碼): 直接建立一個(gè)Indexed8格式的QImage,并讀入數(shù)據(jù)
QImage Qimg(imgWidth,imgHeight,QImage::Format_Indexed8); //QImage(int width, int height, QImage::Format format) Qimg.setColorCount(256); // 灰度級(jí)數(shù)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行的數(shù)據(jù)復(fù)制給一維數(shù)組tempdata//Hidata[]為圖像數(shù)據(jù),事先將圖像數(shù)據(jù)讀入該一維數(shù)組中,該圖像的高為imgWidth、寬為imgHeight}uchar *pDest = Qimg.scanLine(i);memcpy(pDest, tempData, imgWidth); } *qimgHi = Qimg;int pixelindexValue = qimgHi->pixelIndex(304,236); //分析圖像中點(diǎn)(304,236)處的坐標(biāo) 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;運(yùn)行結(jié)果如下:
像素值索引pixelIndex()為: 13 QColor,即pixel()為: QColor(ARGB 1, 0.0509804, 0.0509804, 0.0509804) // 13/255=0.0509804 13 13 13 QRgb為: 4279045389此時(shí)對(duì)應(yīng)的圖像如下:(工作原因,本次所展示圖像均為部分圖像)
可以看出pixelIndex()返回當(dāng)前位置的索引值,而索引值13正好在ColorTable中對(duì)應(yīng)的QRgb也是(13,13,13),而4279045389對(duì)應(yīng)的十六進(jìn)制為: ff0d0d0d。為了證明pixelIndex()返回的就是索引,可以將上述程序做一變化,如下:
for (int i = 0; i < 256; i++) {Qimg.setColor(i, qRgb(255-i, 255-i, 255-i)); }此時(shí)的程序輸出結(jié)果如下,pixelIndex()依然返回當(dāng)前位置的索引值,但是該索引對(duì)應(yīng)的顏色變成了(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對(duì)應(yīng)的圖像為:
用不同的QImage格式,即使用Qimg.convertToFormat(QImage::Format_Grayscale8)語(yǔ)句,得到不同格式的QImage,并取圖像中16個(gè)點(diǎn)的pixelIndex和pixel矩陣進(jìn)行分析,得到列表如下,可見(jiàn)不同格式對(duì)圖像還是有一定影響的,不展開(kāi)分析了。
總結(jié)
以上是生活随笔為你收集整理的QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用for语句打印图形
- 下一篇: VSS 请求程序和 SharePoint