QT QImage, как извлечь RGB?

Я хочу извлечь RGB из каждого пикселя в QImage. В идеале я хочу использовать функцию 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 и т.д....

Ответ 1

QImage img( "Red.jpg" );

if ( false == img.isNull() )
{
    QVector<QRgb> v = img.colorTable(); // returns a list of colors contained in the image 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;
    }

Ответ 2

Ссылка для bits() говорит:

Возвращает указатель на первые пиксельные данные. Это эквивалентно scanLine (0).

Итак, если вы проверите ссылку для scanLine()

Если вы обращаетесь к данным изображения 32-bpp, отбросьте возвращаемый указатель на QRgb * (QRgb имеет 32-разрядный размер) и используйте его для чтения/записи значения пикселя. Вы не можете напрямую использовать указатель uchar *, потому что формат пикселя зависит от порядка байтов на базовой платформе. Для доступа к пикселям используйте qRed(), qGreen(), qBlue() и qAlpha().

Другим вариантом может быть pixel() функция-член.

Надеюсь, что это поможет.

Ответ 3

Одна из проблем с использованием функции bits() заключается в том, что вам нужно знать format исходного изображения. Вы должны преобразовать его в RGB, используя convertToFormat.

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

Теперь, когда вы вызываете биты(), данные будут в формате RGB с правильным выравниванием данных.

uchar *bits = img.bits();

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