Color channels are changing using Qt QImage with data and I don't know why - qt

I have written a function in Qt to extract the data out of an image for the purpose of manipulating it.
I then have another function to reinsert the data back to an image and display it. The problem I am having is that even if I do no manipulation on the pixel data other than extract and reinsert, it is still changing the data. On a yellow image it changes it to turquoise blue when it should remain yellow.
I am including the function code to extract and reinsert as specimen code. I can include more if it is needed such as the display function etc...Does anyone know if I am doing something wrong?
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
filter = "All Picture Files (*.png *.jpg *.jpeg *.bmp *.tif *.tiff)"
";; Bitmap Files (*.bmp) ;; JPEG (*.jpg *.jpeg) ;; PNG (*.png) ;; TIFF (*.tif *.tiff)";
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::importImage()
{
importCancelled = false;
QString filename = QFileDialog::getOpenFileName(nullptr, QObject::tr("Import Image"), "", filter);
if(!filename.isEmpty()){
image.load(filename);
image = image.convertToFormat(QImage::Format_RGBA8888);
}
else {
importCancelled = true;
if(importCancelled){
QString cleanPlateCancelled = "Operation Cancelled";
ui->statusBar->showMessage(cleanPlateCancelled,5000);
return;
}
}
}
void MainWindow::scaleImage()
{
if (image.isNull()){
return;
}
else {
image = image.scaledToHeight(ui->view->height(), Qt::TransformationMode::SmoothTransformation);
}
}
void MainWindow::displayImage()
{
if (image.isNull()){
return;
}
else {
scene = new QGraphicsScene;
showImage = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene->addItem(showImage);
ui->view->setScene(scene);
}
}
void MainWindow::rgbaExtraction()
{
numberOfBytes = static_cast<uint>(image.sizeInBytes());
auto const imageData = image.bits();
rgba = std::vector<uchar>(numberOfBytes,0);
rgbaReset = std::vector<uchar>(numberOfBytes,0);
for (uint i{0}; i < numberOfBytes; ++i) {
rgbaReset[i] = rgba[i] = imageData[i];
}
}
void MainWindow::rgbaInsertion()
{
auto *imageData = new uchar[numberOfBytes];
for (uint i{0};i < numberOfBytes;++i) {
imageData[i] = rgba[i];
}
image = QImage(imageData, image.width(), image.height(), QImage::Format_RGBA8888);
}
void MainWindow::on_importButton_clicked()
{
importImage();
scaleImage();
displayImage();
rgbaExtraction();
}
void MainWindow::on_quitButton_clicked()
{
QApplication::quit();
}
void MainWindow::sceneUpdater()
{
showImage->setPixmap(QPixmap::fromImage(image));
scene->update();
ui->view->update();
}
void MainWindow::on_redSlider_valueChanged(int value)
{
QString redString = QString::number(value);
ui->redLabel->setText(redString);
redDelta = value;
colorRed();
rgbaInsertion();
sceneUpdater();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QImage>
#include <QFileDialog>
#include <string>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_importButton_clicked();
void on_quitButton_clicked();
void on_redSlider_valueChanged(int value);
private:
QGraphicsPixmapItem *showImage;
QGraphicsScene *scene;
QString filter;
QImage image;
bool importCancelled;
QStatusBar *statusBar;
uint numberOfBytes;
std::vector<uchar> rgba;
std::vector<uchar> rgbaReset;
int redDelta{0};
int greenDelta{0};
int blueDelta{0};
int opacityDelta{0};
void importImage();
void scaleImage();
void displayImage();
void rgbaExtraction();
void rgbaInsertion();
void sceneUpdater();
void colorRed(); // Implemented in color.cpp
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
color.cpp
#include <mainwindow.h>
void MainWindow::colorRed()
{
for (uint i{0}; i < rgba.size()*sizeof (rgba[i]);i+=4) {
if(rgbaReset[i] + static_cast<uchar>(redDelta)>=255){
rgba[i] = 255;
}
else {
rgba[i] = rgbaReset[i];// + static_cast<uchar>(redDelta);
}
}
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

The problem is in scaleImage(), because scaledToHeight() returns another image format. You may omit the scale operation, or convert the returned image to Format_RGBA8888:
void MainWindow::scaleImage()
{
if (image.isNull()){
return;
}
else {
image = image.scaledToHeight(ui->view->height(), Qt::TransformationMode::SmoothTransformation)
.convertToFormat(QImage::Format_RGBA8888);
}
}
My recomendation is to add some instrumentation after each image manipulation to check that it has the expected format:
qDebug() << Q_FUNC_INFO << "image format:" << image.format();

Related

How to convert unsigned long long value to a string in qt

I have a calulation that returns large value of factorials of a given number (ex: Factorial of 22 = 17196083355034583040). I want to set the result to a label. I did as shown below.
void Dialog::onNumberChanged(unsigned long long Number)
{
ui->resultPrime->setText(QString::number(Number));
}
MyThread.h
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void run();
bool Stop;
int inputNumber;
unsigned long long resultFactorial;
void Resume();
void Pause();
bool pause;
private:
QMutex sync;
QWaitCondition pauseCond;
// bool pause;
signals:
void NumberChanged(unsigned long long);
public slots:
};
MyThread.cpp
#include "mythread.h"
#include <QDebug>
#include <QMutex>
#include <QWaitCondition>
MyThread::MyThread(QObject *parent):QThread(parent)
{
pause = false;
}
void MyThread::run()
{
QMutex mutex;
int n = inputNumber;
unsigned long long factorial = 1;
// qDebug() << "Enter a positive integer: ";
// cin >> n;
mutex.lock();
if (n < 0)
qDebug() << "Error! Factorial of a negative number doesn't exist.";
else {
for(int i = 1; i <=n; ++i) {
sync.lock();
if(pause)
pauseCond.wait(&sync); // in this place, your thread will stop to execute until someone calls resume
qDebug() << "Paused for now" << pause;
sync.unlock();
factorial *= i;
MyThread().msleep(1000);
emit NumberChanged(factorial);
}
qDebug() << "Factorial of " << n << " = " << factorial;
}
resultFactorial = factorial;
mutex.unlock();
// return factorial;
}
void MyThread::Resume()
{
sync.lock();
pause = false;
sync.unlock();
pauseCond.wakeAll();
}
void MyThread::Pause()
{
sync.lock();
pause = true;
sync.unlock();
}
Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
MyThread *mThread;
private:
Ui::Dialog *ui;
public slots:
void onNumberChanged(unsigned long long);
private slots:
void on_startPrime_clicked();
void on_suspendPrime_clicked();
void on_resumePrime_clicked();
void on_stopPrime_clicked();
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include "mythread.h"
#include <QDebug>
//bool pauseCondition = false;
int statusOfPrimeThread = 0;
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
mThread = new MyThread(this);
connect(mThread, SIGNAL(NumberChanged(long)), this, SLOT(onNumberChanged(long)));
ui->activeStatePrime->setText(QString("Not Started"));
// connect(this, SIGNAL(on_resumePrime_clicked), mThread, SLOT(Resume()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::onNumberChanged(unsigned long long Number)
{
qDebug() << QString::number(17196083355034583040ull);
ui->resultPrime->setText(QString::number(Number));
}
void Dialog::on_startPrime_clicked()
{
// Started
mThread->inputNumber = ui->lineEditPrime->text().toInt();
mThread->start();
if(mThread->isRunning()){
ui->activeStatePrime->setText(QString("Started"));
}
qDebug() << QString::number(17196083355034583040ull);
}
void Dialog::on_suspendPrime_clicked()
{
//Stopped
// mThread->terminate();
// pauseCondition = true;
// mThread->pause = pauseCondition;
mThread->Pause();
ui->activeStatePrime->setText(QString("Paused"));
}
void Dialog::on_resumePrime_clicked()
{
mThread->Resume();
ui->activeStatePrime->setText(QString("Resumed"));
}
void Dialog::on_stopPrime_clicked()
{
mThread->terminate();
ui->activeStatePrime->setText(QString("Terminated"));
}
But the label is not changed. How can I set such a large value, and I am correctly using unsigned long long datatype or is there any other datatype that can be used.

how to get drop events of object which is placed in graphic scene?

i have graphic view(QGraphics view) setted scene(QGraphic scene) i am dropping objects on scene its working fine, i have to assign parameter for dropped object by dragging parameter from parameter list .i have implemented drag drop events of object.but when i am dragging parameter from param list non- acceptance symbol on object.how to assign param to object by dropping ? Any other suggestions and examples are welcome where i can get ideas to implementation.
image of gui
speedometer.cpp
#include <QMimeData>
SpeedoMeter::SpeedoMeter( QWidget *parent ):
QwtDial( parent ),
d_label( "km/h" )
{
setAcceptDrops(true);
}
void SpeedoMeter::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat(paramlistMimeType()))
{
qDebug()<<"dragenter event in speedo" ;
event->accept();
}
}
void SpeedoMeter::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat(paramlistMimeType()))
{
qDebug()<<"dragmove event in speedo" ;
event->acceptProposedAction();
}
}
void SpeedoMeter::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(paramlistMimeType()))
{
qDebug()<<"dragmove event in speedo" ;
event->accept();
}
}
The following example shows how to implement the logic to accept the drag-and-drop:
speedometer.h
#ifndef SPEEDOMETER_H
#define SPEEDOMETER_H
#include <qwt_dial.h>
class SpeedoMeter : public QwtDial
{
public:
SpeedoMeter(QWidget *parent=nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void paintEvent(QPaintEvent *event);
private:
QString d_label;
};
#endif // SPEEDOMETER_H
speedometer.cpp
#include "speedometer.h"
#include <qwt_dial_needle.h>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QPainter>
SpeedoMeter::SpeedoMeter(QWidget *parent):
QwtDial(parent),
d_label( "km/h" )
{
setAcceptDrops(true);
QwtDialSimpleNeedle *nd = new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, Qt::white, Qt::red);
setNeedle(nd);
setValue(80);
}
void SpeedoMeter::dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
event->acceptProposedAction();
}
void SpeedoMeter::dropEvent(QDropEvent *event)
{
const QMimeData *mimedata = event->mimeData();
if(mimedata->hasFormat("application/x-qabstractitemmodeldatalist")){
QString text;
// https://stackoverflow.com/questions/1723989/how-to-decode-application-x-qabstractitemmodeldatalist-in-qt-for-drag-and-drop
QByteArray encoded = mimedata->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded, QIODevice::ReadOnly);
while (!stream.atEnd()) {
int row, col;
QMap<int, QVariant> roleDataMap;
stream >> row >> col >> roleDataMap;
if(roleDataMap.contains(Qt::DisplayRole)){
text = roleDataMap[Qt::DisplayRole].toString();
break;
}
}
// your text
d_label = text;
update();
}
}
void SpeedoMeter::dragMoveEvent(QDragMoveEvent *event)
{
if(event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
event->accept();
}
void SpeedoMeter::paintEvent(QPaintEvent *event)
{
// https://stackoverflow.com/questions/43904204/qwt-dial-show-unit
QwtDial::paintEvent(event);
QPainter painter(this);
painter.setPen(Qt::black);
QFont font;
font.setPointSize(11);
painter.setFont(font);
QString text = QString("%1 %2").arg(value()).arg(d_label);
QPoint c = rect().center();
QSize Size = painter.fontMetrics().size(Qt::TextSingleLine, text);
painter.drawText(QPointF(c.x() -Size.width()/2, c.y() + 2.5*Size.height()), text);
}
main.cpp
#include "speedometer.h"
#include <QApplication>
#include <QGraphicsView>
#include <QHBoxLayout>
#include <QListWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QHBoxLayout *layout = new QHBoxLayout(&w);
QListWidget listWidget;
listWidget.setDragDropMode(QAbstractItemView::DragOnly);
listWidget.addItems({"km/h", "ft/s", "m/s", "miles/h"});
QGraphicsView view;
QGraphicsScene scene;
view.setScene(&scene);
SpeedoMeter speed;
scene.addWidget(&speed);
layout->addWidget(&listWidget);
layout->addWidget(&view);
w.show();
return a.exec();
}
In the following link you can find the complete example.

Showing continuous stream of QImages

I have a set of QImages which come to a function (after a fixed interval of 4 seconds) and the function's job is to update the QLabel to show the new image.
While doing this, I can see a very obvious delay in the image rendering.
I had also followed the suggestions on the link:
Efficient way of displaying a continuous stream of QImages
But, even with using ImageDisplay in the link above, I can see a delay in image rendering.
Can anyone please suggest the best way to do this?
Below is the code.. The images required for the code to run are located at:
https://www.dropbox.com/sh/jiqdfqoiimjs7ei/AAAXezUeeCFyZXjNNOTmWZVga?dl=0
#include <QDialog>
#include <QtGui>
#include <QtCore>
#include <QApplication>
#include <QWidget>
#include <QImage>
class imageDisplay : public QWidget
{
public:
imageDisplay(QWidget*);
~imageDisplay();
void setImage(QImage* img);
private:
QImage* m_image;
protected:
void paintEvent(QPaintEvent* evt);
};
imageDisplay::imageDisplay(QWidget* parent) : QWidget(parent)
{
m_image = 0;
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}
imageDisplay::~imageDisplay()
{
}
void imageDisplay::setImage(QImage* img)
{
m_image = img;
repaint();
}
void imageDisplay::paintEvent(QPaintEvent*)
{
if(!m_image) return;
QPainter painter(this);
painter.drawImage(rect(), *m_image, m_image->rect());
}
////////////////////////////////////
//
int main(int arc, char ** argv)
{
QApplication theApp(arc, argv, true);
QDialog* dlg = new QDialog();
imageDisplay* wgt = new imageDisplay(dlg);
wgt->resize(600,400);
dlg->show();
for(int i = 0 ; i <= 19; ++i)
{
sleep(1);
QString fileName = "aaa" + QString::number(i) + ".png";
QImage* img = new QImage(fileName);
wgt->setImage(img);
}
return theApp.exec();
}

qt gnuplot instance set xrange with variables

I basically just started using Gnuplot and in trying to set xrange/yrange I am not able to find out how to set variable bounds.
For example : instance << "set yrange [-10:10]" works perfectly
but instance << "set yrange [yrange1:yrange2] doesn't.
yrange1, yrange2 are variables in which user input is stored. That way the user can decide the bounds for gnuplot
Is there a simple way to do this?
Edit : Sorry.Here is the code
qtgnuplotlib-example.cpp
//#include <QApplication>
#include "visualization.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
Visualization v;
v.show();
return app.exec();
}
visualization.h
#ifndef VISUALIZATION_H
#define VISUALIZATION_H
#include <QMainWindow>
#include <QtGnuplot/QtGnuplotWidget.h>
#include <QtGnuplot/QtGnuplotInstance.h>
namespace Ui {
class Visualization;
}
class Visualization : public QMainWindow
{
Q_OBJECT
public:
explicit Visualization(QWidget *parent = 0);
~Visualization();
private:
QtGnuplotWidget *widget;
QtGnuplotInstance *instance;
protected:
bool eventFilter(QObject *obj, QEvent *event);
private slots:
void on_actionExit_triggered();
void on_actionOpen_triggered();
void on_pushButton_clicked();
private:
Ui::Visualization *ui;
};
#endif // VISUALIZATION_H
visualization.cpp
#include <QFileDialog>
#include <QFile>
#include <QMessageBox>
#include <QTextStream>
#include <QString>
#include "visualization.h"
#include "ui_visualization.h"
using namespace std;
Visualization::Visualization(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Visualization)
{
ui->setupUi(this);
widget = new QtGnuplotWidget();
widget->installEventFilter(this);
widget->setStatusLabelActive(true);
instance = new QtGnuplotInstance();
instance->setWidget(widget);
}
Visualization::~Visualization()
{
delete ui;
delete instance;
delete widget;
}
void Visualization::on_actionExit_triggered()
{
qApp->quit();
}
void Visualization::on_actionOpen_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QString(),
tr("All Files (*.*)"));
if (!fileName.isEmpty()) {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::critical(this, tr("Error"), tr("Could not open file"));
return;
}
QTextStream in(&file);
QString str = in.readAll();
ui->equationsTxt->setText(str);
file.close();
}
}
bool Visualization::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
if (obj == this->widget) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) {
ui->outputTxt->setText( this->widget->getStatusLabel()->text());
}
}
}
return QObject::eventFilter(obj, event);
}
void Visualization::on_pushButton_clicked()
{
widget->show();
widget->resize(QSize(800,600));
int yrange1 = 5;
int yrange2 = 10;
// *instance <<\
//"set yrange [-1.5:1.5]\nset xrange [-1.5:1.5]\nset isosamples 500,500\nf(x,y)= x**2+y**2-1\nset contour\nset cntrparam levels discrete 0\nset view 0,0\nunset ztics\nunset surface\nsplot f(x,y)\n";
//here is where I am stuck
*instance << "set tics scale 0.75\nset xtics 1\nset ytics 1\nset yrange [-10:10]\nset xlabel 'x'\nset ylabel 'y'\nset zeroaxis\nplot \"<echo '1 2'\" notitle\n";
}
The QtGnuplotInstance class provides an exec method which you can pass a QByteArray with commands:
QtGnuplotInstance instance = new QtGnuplotInstance();
QString command;
QTextStream(&command) << "set yrange [" << yrange1 << ":" << yrange2 << "]";
instance.exec(command.toLocal8Bit());
I cannot test this at the moment, but the direction should be correct.

Multi-threading with Qt

I am building a simple GUI in Qt to carry out some Image Processing in OpenCV. I want to use multi-threading so that the GUI is responsive even if the processing becomes very intensive. To do this I am referring the chapter below to build my framework:
http://www.informit.com/articles/article.aspx?p=1405551&seqNum=3
To begin with, I have 2 push buttons, one to load the image and the other to process it.
I have 2 Labels, one to display the input image and one to display the processed image.
As of now, I am loading my input image using slot and signal mechanism in the main thread and I am creating a new thread for the image flip.
However, when I build my code, I get an error
Undefined symbols for architecture x86_64:
"FlipTransaction::FlipTransaction(int)", referenced from:
MainWindow::flipHorizontally() in mainwindow.o ld: symbol(s) not found for architecture x86_64
When I comment out the slot flipHorizontally(), my code builds fine and am able to load the image.
Thus my processing is not being carried out.
Below is my code. Any help is appreciated
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileDialog>
#include <QStatusBar>
// OpenCV Headers
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> // for cvtColor
// Multi-Threading Headers
#include <QThread>
#include <QMutex>
#include <QQueue>
#include <QWaitCondition>
namespace Ui {
class MainWindow;
}
class Transaction
{
public:
virtual ~Transaction() {}
virtual QImage apply(const cv::Mat source_image, cv::Mat dest_image) = 0;
virtual QString message() = 0;
};
class TransactionThread : public QThread
{
Q_OBJECT
public:
TransactionThread();
~TransactionThread();
void addTransaction(Transaction *transact);
void setImage(const QImage &image);
QImage image();
signals:
void transactionStarted(const QString &message);
void allTransactionsDone();
protected:
void run();
private:
QImage currentImage;
Transaction *EndTransaction;
QQueue<Transaction *> transactions;
QWaitCondition transactionAdded;
QMutex mutex;
cv::Mat source_image;
cv::Mat dest_image;
};
class FlipTransaction : public Transaction
{
public:
FlipTransaction(int orientation);
QImage apply(const cv::Mat source_image, cv::Mat dest_image);
QString message();
private:
int orientation;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
void addTransaction(Transaction *transact);
void drawOut(QImage qimg);
private slots:
void on_pushButton_clicked();
public slots:
void flipHorizontally();
void allTransactionsDone();
private:
Ui::MainWindow *ui;
public:
TransactionThread thread;
cv::Mat source_image; // Input Image Variable
cv::Mat dest_image; // Output Image Variable
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
statusBar()->showMessage(tr("Ready"), 2000);
connect(&thread, SIGNAL(transactionStarted(const QString &)),
statusBar(), SLOT(showMessage(const QString &)));
connect(&thread, SIGNAL(allTransactionsDone()),
this, SLOT(allTransactionsDone()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::drawOut(QImage qimg)
{
// Display on Label
ui->outputLabel->setPixmap(QPixmap::fromImage(qimg));
// Resize the label to fit the image
ui->outputLabel->resize(ui->outputLabel->pixmap()->size());
}
void MainWindow::addTransaction(Transaction *transact)
{
MainWindow::thread.addTransaction(transact);
}
void MainWindow::on_pushButton_clicked()
{
QString filename = QFileDialog::getOpenFileName(this,
tr("Open Image"), ".",tr("Image Files (*.png *.jpg *.jpeg *.bmp *.gif)"));
// Read Image
source_image = cv::imread(filename.toAscii().data());
// Resize Image
cv::resize(source_image, source_image, cv::Size(128,128) , 0, 0);
// Change to RGB format
cv::cvtColor(source_image,source_image,CV_BGR2RGB);
// Convert to QImage
QImage qimg = QImage((const unsigned char*) source_image.data, source_image.cols, source_image.rows, QImage::Format_RGB888); // convert to QImage
// Display on Input Label
ui->inputLabel->setPixmap(QPixmap::fromImage(qimg));
// Resize the label to fit the image
ui->inputLabel->resize(ui->inputLabel->pixmap()->size());
}
void MainWindow::flipHorizontally()
{
MainWindow::thread.addTransaction(new FlipTransaction(int(1)));
}
void MainWindow::allTransactionsDone()
{
statusBar()->showMessage(tr("Ready"), 2000);
}
TransactionThread::TransactionThread()
{
start();
}
TransactionThread::~TransactionThread()
{
{
QMutexLocker locker(&mutex);
while(!transactions.isEmpty())
delete transactions.dequeue();
transactions.enqueue(EndTransaction);
transactionAdded.wakeOne();
}
wait();
}
void TransactionThread::addTransaction(Transaction *transact)
{
QMutexLocker locker(&mutex);
transactions.enqueue(transact);
transactionAdded.wakeOne();
}
void TransactionThread::setImage(const QImage &image)
{
QMutexLocker locker(&mutex);
currentImage = image;
}
QImage TransactionThread::image()
{
QMutexLocker locker(&mutex);
return currentImage;
}
void TransactionThread::run()
{
Transaction *transact = 0;
QImage oldImage;
forever {
{
QMutexLocker locker(&mutex);
if (transactions.isEmpty())
transactionAdded.wait(&mutex);
transact = transactions.dequeue();
if (transact == EndTransaction)
break;
oldImage = currentImage;
}
emit transactionStarted(transact->message());
QImage newImage = transact->apply(source_image, dest_image);
// QImage newImage = transact->apply(oldImage);
delete transact;
{
QMutexLocker locker(&mutex);
currentImage = newImage;
if (transactions.isEmpty())
emit allTransactionsDone();
}
}
}
QImage FlipTransaction::apply(const cv::Mat source_image, cv::Mat dest_image)
{
// Process Image
cv::flip(source_image, dest_image, orientation);
// Change to RGB format
cv::cvtColor(dest_image,dest_image,CV_BGR2RGB);
// Convert to QImage
QImage qimg = QImage((const unsigned char*) dest_image.data, dest_image.cols, dest_image.rows, QImage::Format_RGB888);
return qimg;
}
QString FlipTransaction::message()
{
if (orientation == 1) {
return QObject::tr("Flipping image horizontally...");
} else {
return QObject::tr("Flipping image vertically...");
}
}

Resources