QT QImage,如何提取RGB?

13

我想从QImage中的每个像素提取RGB。理想情况下,我想使用img.bits()函数。

QImage img;

if( img.load("Red.jpg") )
{
    uchar *bits = img.bits();

    for (int i = 0; i < 12; i++)
    {
        std::cout << (int) bits[i] << std::endl;
    }
}

如何操作返回的位?我期望看到全红,因为这张图片是在Paint中创建的纯红色图像。然而,我得到了36、27、237、255、36等不同的值...


2
使用bits()读取图像数据与图像格式息息相关。尝试将图像格式转换为更适合您场景的格式,例如img = img.convert(QImage::Format_ARGB32)。然后,如果我没记错的话,字节应该是0, 255, 0, 0, [loop] - Stefan Majewsky
4个回答

17
QImage img( "Red.jpg" );

if ( false == img.isNull() )
{
    QVector<QRgb> v = img.colorTable(); // returns a list of colors contained in the image's color table.

    for ( QVector<QRgb>::const_iterator it = v.begin(), itE = v.end(); it != itE; ++it )
    {
        QColor clrCurrent( *it );
        std::cout << "Red: " << clrCurrent.red()
                  << " Green: " << clrCurrent.green()
                  << " Blue: " << clrCurrent.blue()
                  << " Alpha: " << clrCurrent.alpha()
                  << std::endl;
    }
}

然而,上述示例确实返回了颜色表。颜色表不包括相同的颜色两次。它们将按出现顺序添加一次。


如果你想获取每个像素的颜色,可以使用以下行:

for ( int row = 1; row < img.height() + 1; ++row )
    for ( int col = 1; col < img.width() + 1; ++col )
    {
        QColor clrCurrent( img.pixel( row, col ) );

        std::cout << "Pixel at [" << row << "," << col << "] contains color ("
                  << clrCurrent.red() << ", "
                  << clrCurrent.green() << ", "
                  << clrCurrent.blue() << ", "
                  << clrCurrent.alpha() << ")."
                  << std::endl;
    }

你为什么从行 = 1 开始,而不是行 = 0? - ABCD
因为我记得图像或像素图从1开始索引,而不是0。可能是我搞错了。你试过了吗?是从0开始还是怎么样? - Pie_Jesu
在QT5上尝试了一下。rowcol应该在0到width-1/height-1的范围内。而且您在for循环中混淆了width()height() - Astronavigator
1
Qt文档指出,QImage::pixel() / setPixel() 操作较慢。如果您计划处理大量像素,则建议使用 bits()scanLine()(以及它们各自的const版本)。 - Paulo Carvalho

6

bits() 的参考文档表示:

返回指向第一个像素数据的指针。这相当于 scanLine(0)。

所以,如果您查看scanLine()的参考文档

如果您正在访问32 bpp图像数据,请将返回的指针转换为QRgb*(QRgb具有32位大小),并使用它来读取/写入像素值。您不能直接使用uchar*指针,因为像素格式取决于基础平台上的字节顺序。使用qRed()、qGreen()、qBlue()和qAlpha()来访问像素。

另一个选择可能是pixel()成员函数。

希望能帮到您。


4
使用bits()函数的一个问题是需要知道原始图像的格式。您应该使用convertToFormat将其转换为RGB。
img = img.convertToFormat(QImage::Format_RGB888);

现在,当您调用bits()函数时,数据将以RGB格式呈现,并具有适当的数据对齐方式。
uchar *bits = img.bits();

for (int i = 0; i < (img.width() * img.height() * 3); i++)
{
    std::cout << (int) bits[i] << std::endl;
}

1
你可以将img.bits()转换为类型为QRgb的指针。因此,您不需要知道图像的类型。只需迭代每个像素并使用qRed()、qGreen()、qBlue()等即可。 - 501 - not implemented
@501-notimplemented,你怎样转换它?我试过 const QRgb *rawPixelData = static_cast<const QRgb *>(pixelSource.constBits()); 但是显然这是一个无效的静态转换…… - Troyseph
嗨@Troyseph,你可以使用QRgb *rawPixelData= (QRgb*)(pixelSource.bits())而不需要static_cast。 - 501 - not implemented
@501-notimplemented C风格转换... 真恶心=P 那不是最终变成reinterpret_cast了吗? - Troyseph
必须使用reinterpret_cast。因此请使用C风格的转换! - Петър Петров

0
在Qt 5.6中引入了QColor QImage::pixelColor(int x, int y)方法,因此您可以直接从图像像素中获取颜色信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接