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


  • Lifetime Qt Champion

    Hi,

    Are you generating the RVMessage ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.