Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QT QImage, how to extract RGB?

Tags:

c++

qt

qimage

I want to extract RGB from each pixel in QImage. Ideally, I want to use the img.bits() function.

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;
    }
}

How to manipulate the returned bits? I expected all red because the picture is a pure red image created in Paint. However, I get 36, 27, 237, 255, 36 etc...

like image 835
SmallChess Avatar asked Sep 12 '12 06:09

SmallChess


3 Answers

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;
    }
}

However this example above does returns the color table. Color table does not includes same colors twice. They will be added once in order of appearance.
If you want to get each pixels color, you can use next lines:

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;
    }
like image 182
Pie_Jesu Avatar answered Oct 22 '22 08:10

Pie_Jesu


Reference for bits() says:

Returns a pointer to the first pixel data. This is equivalent to scanLine(0).

So if you check reference for scanLine()

If you are accessing 32-bpp image data, cast the returned pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. You cannot use the uchar* pointer directly, because the pixel format depends on the byte order on the underlying platform. Use qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels.

One other option would probably be pixel() member function.

Hope that helps.

like image 6
jrok Avatar answered Oct 22 '22 10:10

jrok


One of the problems with using the bits() function is that you need to know the format of the original image. You should convert it to RGB by using convertToFormat.

img = img.convertToFormat(QImage::Format_RGB888);

Now, when you call bits(), the data will be in the RGB format with the proper data alignment.

uchar *bits = img.bits();

for (int i = 0; i < (img.width() * img.height() * 3); i++)
{
    std::cout << (int) bits[i] << std::endl;
}
like image 4
Keith Avatar answered Oct 22 '22 09:10

Keith