Generating image from message structure
-
Hi,
I'm creating an app that according with some messages received will create a grayscale image.
Every message contains the color information for a rectangle that is part of the complete image coded to 8 bits (the complete image is 2048 x 2048 pixels).I need 2 differents methods to show this messages:
- One that is a kind of "play mode" where everything received will be played.
- Anotherone where you can show message by message.
Now, I'm using a queue,where I store every message I receive:
{ m_mutex.lock(); m_queue.enqueue(message); m_mutex.unlock(); } bool MessagesDB::isEmpty() { return m_queue.isEmpty(); } bool MessagesDB::getMessage(RVMessage& message) { if (!isEmpty()) { m_mutex.lock(); message = m_queue.dequeue(); m_mutex.unlock(); return true; } return false; }
Then from the MainWindow process I call the different methods to generate the image in a different thread:
#include "MainWindow.h" #include <MessagesDB.h> #include <utils.h> #include <iostream> #include <WApp.h> MainWindow::MainWindow(QWidget *parent) : QWidget(parent), m_timer() { setWindowTitle("Afl Raw Video Output Testsuite"); m_layoutV = new QVBoxLayout(); m_layoutV->setContentsMargins(0, 0, 0, 0); m_layoutV->setSpacing(0); m_layoutScrollArea = new QVBoxLayout(); m_layoutScrollArea->setContentsMargins(0, 0, 0, 0); m_layoutScrollArea->setSpacing(0); m_layoutH = new QHBoxLayout(); m_layoutH->setContentsMargins(0, 0, 0, 0); m_layoutH->setSpacing(0); m_layoutVToolbar = new QVBoxLayout(); m_layoutVToolbar->setContentsMargins(0, 0, 0, 0); m_layoutVToolbar->setSpacing(0); m_gridLayout = new QGridLayout(); m_gridLayout->setSpacing(8); m_gridLayout->setRowStretch(0, 1); m_gridLayout->setRowStretch(1, 1); m_gridLayout->setRowStretch(2, 1); m_gridLayout->setRowStretch(3, 1); m_scrollArea = new QScrollArea(); m_scrollArea->setFixedSize(QSize(1220, 820)); img = new QLabel(); img->setFixedSize(QSize(2048, 2048)); m_scrollArea->setWidget(img); m_scrollArea->setLayout(m_layoutScrollArea); m_layoutV->addWidget(m_scrollArea); runButton = new QPushButton("Next"); m_layoutVToolbar->addWidget(runButton); playButton = new QPushButton("Play"); m_layoutVToolbar->addWidget(playButton); m_layoutH->addLayout(m_layoutVToolbar); m_layoutH->setStretch(0,1); m_layoutH->addLayout(m_gridLayout); m_layoutH->setStretch(1,1); m_layoutV->addLayout(m_layoutH); setLayout(m_layoutV); // the QImage generation thread qRegisterMetaType<QImage>("QImage"); m_generateImageThread = new GenerateImageThread(); // slot to respond to the QImage generation thread // - display the image in a window connect(runButton, SIGNAL(clicked()), this, SLOT(generateImage())); connect(playButton, SIGNAL(clicked()), this, SLOT(playMode())); connect(m_generateImageThread, SIGNAL(imageReady(const QImage &)), this, SLOT(displayImage(const QImage &))); m_timer = new QTimer(); m_timer->setInterval(20); connect(m_timer,SIGNAL(timeout()),this,SLOT(generateImage())); } MainWindow::~MainWindow() { if (img) delete img; } //-------------------- // slot to run thread //------------------- void MainWindow::generateImage() { if (!m_generateImageThread->isRunning()) { m_generateImageThread->start(); } } //-------------------- // Play mode //------------------- void MainWindow::playMode() { if (!m_timer->isActive()) { m_timer->start(); playButton->setText("Stop"); } else { m_timer->stop(); playButton->setText("Start"); } } //------------------- // display the QImage //------------------- void MainWindow::displayImage(const QImage &image) { img->setPixmap(QPixmap::fromImage(image)); }
As you can see, for running the "play mode" I have created a timer that runs/stops when you press the button.
And this is the thread that generates the image:
GenerateImageThread::GenerateImageThread(QObject *parent) : QThread(parent), m_image(MAX_X, MAX_Y, QImage::Format_RGB32) { //Initialize colors for (int i = 0; i < MAX_COLORS;++i) { m_colors[i] = QColor(i, i, i); } } void GenerateImageThread::run() { RVMessage message(RVMessage::E_8BITS_PIXEL); while (MessagesDB::Instance().getMessage(message)) { int width = message.getRightCoord() - message.getLeftCoord() + 1; int height = message.getBottomCoord() - message.getTopCoord() + 1; for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { m_image.setPixel(i + message.getLeftCoord(), j + message.getTopCoord(), m_colors[message.getData(i, j)].rgb()); } } emit imageReady(m_image); } }
My two main problems are that first, I am not getting the best performance results while running this. Do you have any idea about how to improve this.
And second, I am gonna have the need to send certain information from the messages (header information) to the main window apart of the image. Do you think is a good idea to send a new signal with this information?Thanks in advance
-
Hi,
Are you generating the RVMessage ?