Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > QImage + массивы сырых данных


Автор: maxi91m 23.4.2013, 17:03
Помогите разобраться в  Qimage

Есть трехмерный массив данных(данные могут быть целого не отрицательного типа)
Массив создан динамически, данные считаны из бинарного файла.

Необходимо добиться максимально быстрого отображения полученного данных в градациях серого.

Объясните как лучше передавать данные в QImage.

Данные в массиве в виде одного числа, как мне уложить это число в  QByteArray?
Если  QImage, как я понял хранит данные в виде пикселов(три компоненты), то мне надо размножить мое число(положим, что в массиве числа от 0-255)
Например есть число типа int  123 в массиве, тогда в массив  QByteArray мне необходимо записать три подряд одинаковых числа, чтобы задать значение одного пиксела,  ТАК?
int         QByteArray
123     (123 123 123)
 а так как QByteArray содержит char то мне необходимо сделать  преобразование типа из  int в char

Так все на самом деле, или нет?

Если устанавливать по писелам, то будет тормознуто?
Какой лучше виджет использовать для отображения QImage, если потом  поверх полученного изображения необходимо вывести еще графические данные(что то вроде линии, которая показывает место среза в других плоскостях), через которые можно будет управлять данными выводимыми на других виджетах?

Автор: Jeka178RUS 23.4.2013, 17:24
Используй http://qt-project.org/doc/qt-4.8/qimage.html#QImage-4
с форматом QImage::Format_Indexed8

А теперь внимание вопрос: почему исходный массив трехмерный?

Автор: maxi91m 23.4.2013, 17:50
Цитата(Jeka178RUS @  23.4.2013,  18:24 Найти цитируемый пост)
А теперь внимание вопрос: почему исходный массив трехмерный? 

массив трехмерный, потому что данные в файле это значения снятые на МРТ, в трехмерном пространстве.
Каждый срез массива представляет какую то картинку, и ее надо вывести в градациях серого.

Пишу 
Код

unsigned char  bufffer[4] = {123,123,123,123};
    QByteArray arr((const char*)bufffer);
    QImage img(2, 2, QImage::Format_Indexed8);
    img.loadFromData(arr);
    QRgb rgb = img.pixel(1 ,1);
    QColor color(rgb);
    qDebug()<<color.red();


получаю

Код

QImage::pixel: coordinate (1,1) out of range
0
 


что я делаю не так?

Так получилось 
Код

 uchar  buffer[16] = {255,123,123,123,255,123,123,123,255,123,123,123,255,123,123,123};
QImage img((uchar*buffer, 4, 4, QImage::Format_Indexed8);



Но вопрос остается, что я делаю не так с  QByteArray

Автор: Amp 23.4.2013, 19:31
Format_Indexed8 подразумевает наличие палитры.

Автор: maxi91m 23.4.2013, 19:43
Цитата(Amp @  23.4.2013,  20:31 Найти цитируемый пост)
Format_Indexed8 подразумевает наличие палитры. 


Если передавать uchar  buffer[16] то все нормально(без установки палитры) пикселы закрашиваются, 
но не работает 
Код

 QRgb rgb = img.pixel(1 ,1);
    QColor color(rgb);
    qDebug()<<color.red();

а с QByteArray  не получается и просто вывести пикселы не получается.

Автор: Amp 23.4.2013, 20:08
У тебя loadFromData наверняка вернул 0, потому что он не принимает такие сырые данные.

Добавлено через 13 минут и 57 секунд
Как-то так. Причем надо учесть, что в исходном массиве данные должны быть выровнены на границу слова.

Код

uchar buffer[] = {0, 0, 0, 0, 1, 1, 0, 0};

QImage img(buffer, 2, 2, QImage::Format_Indexed8);

QVector<QRgb> palette;
palette.push_back(qRgb(255, 0, 0));
palette.push_back(qRgb(0, 128, 0));

img.setColorTable(palette);
    
qDebug() << QColor(img.pixel(0, 0));
qDebug() << QColor(img.pixel(1, 0));
qDebug() << QColor(img.pixel(0, 1));
qDebug() << QColor(img.pixel(1, 1));

Автор: maxi91m 23.4.2013, 20:23
Цитата(Amp @  23.4.2013,  21:08 Найти цитируемый пост)
У тебя loadFromData наверняка вернул 0, потому что он не принимает такие сырые данные.  

Точно, вернул  false

А в чем сырость данных заключается, передаю же в QByteArray  такой массив
Код

 uchar  buffer[16] = {255,123,123,123,255,123,123,123,255,123,123,123,255,123,123,123};//для примера


Ваш код вывел мне 
Код

QColor(ARGB 1, 1, 0, 0) 
QColor(ARGB 1, 1, 0, 0) 
QColor(ARGB 1, 0, 0.501961, 0) 
QColor(ARGB 1, 0, 0.501961, 0) 


но я не пойму если изображение  2x2 то в него попали  только  четыре нуль, а это значит что должно выводить четыре красных цвета, а вывело 2 красных и 2  других.

Как данные асcоцеируются из массива с QImage?
 я думал значение с пикселом, а тут как-то иначе.

Автор: Amp 23.4.2013, 20:38
Цитата(maxi91m @  23.4.2013,  20:23 Найти цитируемый пост)
А в чем сырость данных заключается, передаю же в QByteArray  такой массив

Данные должны быть в определенном графическом формате, например jpg, а не просто набор чисел. В документации же написано.

Автор: maxi91m 23.4.2013, 20:42
Цитата(Amp @  23.4.2013,  21:38 Найти цитируемый пост)
анные должны быть в определенном графическом формате, например jpg, а не просто набор чисел. В документации же написано. 


А чем тогда отличаются данные uchar? такие же числа лежат.

Автор: Amp 23.4.2013, 21:04
Твои данные не являются ни jpg, ни png, ни tga, ни bmp, ни каким-либо другим форматом, который поддерживает Qt. Это просто raw bitmap data в формате, который только тебе и известен. loadFromData читает массив данных и если формат прямо не задан, то метод по первым байтам и известным сигнатурам пытается определить с чем имеет дело. Естественно ничего не выходит и он возвращает false. В документаци все подробно написано.

Автор: maxi91m 23.4.2013, 21:11
Цитата(Amp @  23.4.2013,  22:04 Найти цитируемый пост)
Твои данные не являются ни jpg, ни png, ни tga, ни bmp, ни каким-либо другим форматом, который поддерживает Qt. Это просто raw bitmap data в формате, который только тебе и известен. loadFromData читает массив данных и если формат прямо не задан, то метод по первым байтам и известным сигнатурам пытается определить с чем имеет дело. Естественно ничего не выходит и он возвращает false. В документаци все подробно написано. 

С этим разобрались, теперь надо понять, по какому принципу надо укладывать данные в массив  uchar? в вашем случае, когда создаешь таблицу цветов, просто если ее не создавать, каждый элемент массива это цвет пиксела в градациях серого(0-255).
А у вас не пойму по какому алгоритму идет присвоение цвета пикселу, и сколько чисел отвечают за один пиксел( по логике 2)?

После длительного изменения параметров прихожу к выводу что длина слова 4 байта, а значит каждый раз надо добивать каждую строку.
Так?

Автор: Jeka178RUS 24.4.2013, 10:30
Если хочешь использовать QByteArray c QImage используй метод data() в качестве параметра конструктора.

Палитру можешь задать как указано тут http://stackoverflow.com/questions/13678093/display-grayscale-image-using-qt

Автор: maxi91m 24.4.2013, 20:00
Код

    QImage img((uchar*)buffer, 5, 5, QImage::Format_Indexed8);
    img.setColorCount(255);
    for(int i = 0; i < 255; i++)
        img.setColor(i, qRgb(i,i,i));
    qDebug() << QColor(img.pixel(1, 1));


Вываливается 

Код

ASSERT failure in QVector<T>::at: "index out of range", file q:\qt5_workdir\w\s\qtbase\include\qtcore\../../src/corelib/tools/qvector.h, line 348
Debug Error!

Program: C:\Qt\Qt5.0.2\5.0.2\msvc2012_64\bin\Qt5Cored.dll
Module: 5.0.2
File: global\qglobal.cpp
Line: 1985

ASSERT failure in QVector<T>::at: "index out of range", file q:\qt5_workdir\w\s\qtbase\include\qtcore\../../src/corelib/tools/qvector.h, line 348

(Press Retry to debug the application)


убираю qDebug() << QColor(img.pixel(1, 1)); то все собирается.
Что тут не так?

------------------------------------------
Вопрос снимается, там и правда лежали данные которые вне диапазона палитры

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)