Я получаю изображения с камеры с помощью SDK, который возвращает данные в массиве без знака. Однако этот SDK не предлагает функциональность для отображения данных, поэтому я попытался реализовать это, используя Qt 4.8 под Ubuntu 12.04.
В настоящий момент мой код выглядит так:
#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
while (..) // condition which breaks after a number of images where grabbed
{
// Get the image from the third party SDK into an unsigned char array
// named pImageBuffer
QImage image ((unsigned char *) pImageBuffer,
GetWidth(),
GetHeight(),
QImage::Format_Indexed8);
QVector<QRgb> colorTable(256);
for(int i=0;i<256;i++)
colorTable[i] = qRgb(i,i,i);
image.setColorTable(colorTable);
QPixmap pixmap = QPixmap::fromImage(image);
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
scene.addItem(item);
view.show();
a.exec();
}
}
Это работает, как и ожидалось, изображения отображаются правильно. Однако a.exec() блокирует основной поток, пока я не закрою QtWindow.
Есть ли простой способ изменить это, поэтому окно остается открытым все время и просто обновляет отображаемое изображение? На данный момент производительность не имеет значения, но мне нужно сохранить код простым.
Хотя вызов QApplication :: processEvents будет работать, это просто взлом, а не лучшее решение.
В идеале, захват изображения должен работать на отдельном потоке как объект, полученный из QObect. Этот объект излучает сигналы полученных ими изображений, которые принимаются объектом в основном потоке.
Получающий объект может затем установить изображение на объект QGraphicsPixmapItem.
Обратите внимание, что код в вопросе создает новый QGraphicsPixmapItem для каждого изображения, полученного от граббера. Предполагая, что вы хотите создать анимированное изображение, вы должны создавать и добавлять только один объект QGraphicsPixmapItem.
Использование QThread очень просто, и если вы этого не сделали раньше, я предлагаю вам прочитать эту статью, в которой четко объясняется, что делать, с примером кода.
class ImageGrabber
{
Q_OBJECT
public:
ImageGrabber(QPixmapItem* item) : _item(item)
{
connect( &timer, SIGNAL(timeout()), this, SLOT(grabImage()) )
_timer.start(33); // 33 ms between timeouts.
}
public slots:
void grabImage()
{
// Update image
QImage image(...);
_item->setPixmap( QPixmap::fromImage(image) );
}
private:
QPixmapItem* _item;
QTimer _timer;
};
int main(...)
{
QApplication a(argc,argv);
...
view.show();
QGraphicsPixmapItem* pixmapItem = scene.addPixmap(QPixmap());
ImageGrabber ig(pixmapItem);
return a.exec();
}