QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)
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,會看到如下信息:
| 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,即對于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值,例如:
而對于基于索引的單色圖和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,并讀入數據
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此時對應的圖像如下:(工作原因,本次所展示圖像均為部分圖像)
可以看出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對應的圖像為:
用不同的QImage格式,即使用Qimg.convertToFormat(QImage::Format_Grayscale8)語句,得到不同格式的QImage,并取圖像中16個點的pixelIndex和pixel矩陣進行分析,得到列表如下,可見不同格式對圖像還是有一定影響的,不展開分析了。
總結
以上是生活随笔為你收集整理的QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用for语句打印图形
- 下一篇: VSS 请求程序和 SharePoint