How to define the size of QT Opengl framebuffer - qt

In GLFW we define the size of the Opengl framebuffer through this command.
GLFWwindow* window = glfwCreateWindow(1920, 1080, "Test Window", NULL, NULL);
This creates a opengl window of size 1920 X 1080 and the default frame buffer of Opengl is also of the same size.
How can we do the same in QT
This is how am i currently setting parameters for the opengl rendering.
QGLFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSampleBuffers(true);
format.setSamples(4);
format.setSwapInterval(1);
QGLFormat::setDefaultFormat(format);
///////////////////////////////////// The GlWidget Class ////////////////
class GLWidget : public QOpenGLWidget
{
Q_OBJECT;
public:
explicit GLWidget(QWidget *parent = 0);
// ~GLWidget();
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
QTimer timer;
QElapsedTimer elapsedtimer;
private:
int width;
int height;
};
///////////////////////////////////////////////////////////////////////////////////
GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
}
//////////////////////////////////////////////////////////////////////////////////////////
void GLWidget::initializeGL()
{
GLenum GlewInitResult;
glewExperimental = GL_TRUE;
GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult) // Check if glew is initialized properly
{
QMessageBox msgBox;
msgBox.setText("Not able to Initialize Glew");
msgBox.exec();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
void GLWidget::paintGL()
{
// Painting commands here which are opengl commands using GLEW.
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Render in default framebuffer
glClear(GL_COLOR_BUFFER_BIT);
RenderCube();
}
///////////////////////////////////////////////////////////////////////////////////////////
IN the Main function
QApplication application(argc, argv);
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(format);
return application.exec();

You can specify the size using QOpenGLFramebufferObject
The QOpenGLFramebufferObject class encapsulates an OpenGL framebuffer
object
The constructor accepts width and height. There are other overloaded constructors.
Look for documentation here.
https://doc.qt.io/qt-5/qopenglframebufferobject.html#QOpenGLFramebufferObject-5
Call bool QOpenGLFramebufferObject::bind() to switch from system provided default framebuffer. Call bool QOpenGLFramebufferObject::release() to get back to the default framebuffer.
example:
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
QOpenGLFramebufferObject* frameBufferObject = new QOpenGLFramebufferObject(1920, 1080, format);
frameBufferObject->bind();

Related

How to Zoom / Fit Image to GraphicsView

I read a lot of posts/threads but I can't get it to work.
I'd like to fit every Image to a GraphicsView regardless if it is smaller or bigger then the view.
What's wrong?
void frmMain::on_btLoadImage_clicked()
{
QGraphicsScene *scene;
QPixmap image;
QString imgPath = "O:/IMG_0001.JPG";
QRectF sceneRect = ui->imgMain->sceneRect();
image.load(imgPath);
image.scaled (sceneRect.width (),sceneRect.height (), Qt::KeepAspectRatio, Qt::SmoothTransformation);
scene = new QGraphicsScene(this);
scene->addPixmap(image);
scene->setSceneRect(sceneRect); //image.rect());
//ui->imgMain->fitInView (scene->itemsBoundingRect(), Qt::KeepAspectRatio); //ui->imgMain->width (), ui->imgMain->height ());
ui->imgMain->setScene(scene);
}
Here is a basic custom QGraphicsView implementation which displays one image and keeps it sized/scaled to fit the available viewport space. Note that the image needs to be rescaled every time the viewport size changes, which is why it is simplest to reimplement the QGraphicsView itself and change the scaling in resizeEvent(). Although it could be done inside a custom QGraphicsScene instead. (Or, really, a number of other ways depending on the exact needs.)
The same technique could be used to keep a QGraphicsWidget as the root item in the scene to always take up the full space. Then a layout could be used in the widget to keep children aligned/resized/positioned/etc.
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
class GrpahicsImageView : public QGraphicsView
{
Q_OBJECT
public:
using QGraphicsView::QGraphicsView;
public slots:
void setImage(const QString &imageFile)
{
if (m_imageFile != imageFile) {
m_imageFile = imageFile;
loadImage(viewport()->contentsRect().size());
}
}
void setImageScaleMode(int mode)
{
if (m_scaleMode != Qt::AspectRatioMode(mode)) {
m_scaleMode = Qt::AspectRatioMode(mode);
if (m_item)
loadImage(viewport()->contentsRect().size());
}
}
void loadImage(const QSize &size)
{
if (!scene())
return;
if (m_imageFile.isEmpty()) {
// remove existing image, if any
removeItem();
return;
}
// Load image at original size
QPixmap pm(m_imageFile);
if (pm.isNull()) {
// file not found/other error
removeItem();
return;
}
// Resize the image here.
pm = pm.scaled(size, m_scaleMode, Qt::SmoothTransformation);
if (createItem())
m_item->setPixmap(pm);
}
protected:
void resizeEvent(QResizeEvent *e) override
{
QGraphicsView::resizeEvent(e);
if (!scene())
return;
// Set scene size to fill the available viewport size;
const QRect sceneRect(viewport()->contentsRect());
scene()->setSceneRect(sceneRect);
// Keep the root item sized to fill the viewport and scene;
if (m_item)
loadImage(sceneRect.size());
}
private:
bool createItem() {
if (m_item)
return true;
if (!m_item && scene()) {
m_item = new QGraphicsPixmapItem();
scene()->addItem(m_item);
return true;
}
return false;
}
void removeItem()
{
if (m_item) {
if (scene())
scene()->removeItem(m_item);
delete m_item;
m_item = nullptr;
}
}
Qt::AspectRatioMode m_scaleMode = Qt::KeepAspectRatio;
QString m_imageFile;
QGraphicsPixmapItem *m_item = nullptr;
};
Usage example:
#include <QApplication>
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog d;
d.setLayout(new QVBoxLayout);
d.resize(350, 350);
GrpahicsImageView *view = new GrpahicsImageView(new QGraphicsScene, &d);
QComboBox *imgCb = new QComboBox(&d);
imgCb->addItems({
"./so-logo.png",
"./se-logo.png",
"./su-logo.png"
});
QComboBox *scaleCb = new QComboBox(&d);
scaleCb->addItems({
"IgnoreAspectRatio",
"KeepAspectRatio",
"KeepAspectRatioByExpanding"
});
QHBoxLayout *cbLayout = new QHBoxLayout;
cbLayout->setSpacing(9);
cbLayout->addWidget(imgCb);
cbLayout->addWidget(scaleCb);
d.layout()->addItem(cbLayout);
d.layout()->addWidget(view);
QObject::connect(imgCb, QOverload<const QString &>::of(&QComboBox::currentIndexChanged), view, &GrpahicsImageView::setImage);
QObject::connect(scaleCb, QOverload<int>::of(&QComboBox::currentIndexChanged), view, &GrpahicsImageView::setImageScaleMode);
view->setImageScaleMode(scaleCb->currentIndex());
view->setImage(imgCb->currentText());
return d.exec();
}
https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png
https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/se-logo.png
https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/su-logo.png

How to initialize custom QQuickItem in Qt

I have implemented custom QQuickItem which is exposed to QML. Now it becomes more useful item in all platforms but due some reasons in Windows we are not using QML it's pure QT Application.
But I am not able to instantiate custom QQuickItem in Qt, could some one help me out of this?
Here is the code:
customItem.h
#include <QQuickItem>
#include <QQuickWindow>
class CustomItem : public QQuickItem
{
Q_OBJECT
public:
explicit CustomItem(QQuickItem *parent = 0);
signals:
public slots:
void paint();
private slots:
void handleWindowChanged(QQuickWindow * win);
};
customItem.cpp:
#include "customItem.h"
CustomItem::CustomItem(QQuickItem *parent) :
QQuickItem(parent)
{
connect(this, &CustomItem::windowChanged, this, &CustomItem::handleWindowChanged);
}
void CustomItem::paint()
{
QQuickWindow * win = window();
qreal ratio = win->devicePixelRatio();
int w = int(ratio * win->width());
int h = int(ratio * win->height());
glViewport(0, 0, w, h);
glDisable(GL_DEPTH_TEST);
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
}
void CustomItem::handleWindowChanged(QQuickWindow * win)
{
if (win) {
connect(win, &QQuickWindow::beforeRendering, this, &CustomItem::paint, Qt::DirectConnection);
win->setClearBeforeRendering(false);
}
}
main.cpp:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQuickView *view = new QQuickView ();
QWidget *container = QWidget::createWindowContainer(view);
CustomItem *customitem = new CustomItem();///how can i set it view
container->show();
return app.exec();
}
Issue:
Not able to instantiate CustomItem

QImage and Threads

I am having problems with QImages and Qthreads.
I am trying to load big images in a Thread and then display them as QPixmap on a QLabel.
My problem is that as long as I don't use a different thread to load the QImages, everything is perfect but as soon as I use a different thread, nothing is renderder.
Though I still have a valid size for my QImage.
The thing that puzzles me is that, if I just comment the 22nd line in the cpp that moves the loader to the other thread, the label displays nicely.
Does anyone have an idea?
Here is my very simplified code:
Header :
class Loader : public QObject
{
Q_OBJECT
public:
explicit Loader(QObject *parent = 0);
signals:
void imageLoaded(QString, const QImage &);
public slots:
void loadImage(const QString& fichier);
};
namespace Ui {
class MainWindow;
}
class LoaderImages;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void loadImage(const QString& dossier);
private slots:
void imageAvailable(const QString& dossier, const QImage& img);
private:
Ui::MainWindow *ui;
//QString mDossier;
Loader* mLoader;
//QMap<QString, QImage*> mMapDesImages;
int mWidth;
};
cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QPixmap>
#include <QImage>
#include <QDir>
#include <QThread>
#include <QDebug>
#include <QLabel>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mLoader(new Loader(NULL)),
mWidth(0)
{
ui->setupUi(this);
QThread* thread = new QThread(this);
mLoader->moveToThread(thread);
thread->start();
connect(this, SIGNAL(loadImage(QString)), mLoader, SLOT(loadImage(QString)));
connect(mLoader, SIGNAL(imageLoaded(QString,QImage)), this, SLOT(imageAvailable(QString,QImage)));
emit loadImage("C:/img.jpg");
}
void MainWindow::imageAvailable(const QString &dossier, const QImage& img)
{
mWidth += (img.width() + 20);
ui->mScrollContent->setMinimumSize(mWidth,img.height());
QLabel* lab = new QLabel(ui->mScrollContent);
lab->setFixedSize(img.width(), img.height());
lab->setGeometry(mWidth - img.width() + 20, 0, img.width(), img.height());
lab->setPixmap(QPixmap::fromImage(img));
}
MainWindow::~MainWindow()
{
delete mLoader;
delete ui;
}
Loader::Loader(QObject *parent) :
QObject(parent)
{
}
void Loader::loadImage(const QString& fichier)
{
QImage* image = new QImage(fichier);
emit imageLoaded(fichier, *image);
}
Thx!
There are several mistakes:
You're not showing the label. When the image loader is in the GUI thread, the image is loaded and the label added to the contents pane before the main window is shown. Since the parent is shown, the children become visible.
When the loading is done in another thread, you'll be adding image labels to a widget that's already shown. Such child widgets are not visible unless you explicitly show() them.
You're leaking the image in loadImage. There's no reason to put that QImage on the heap.
You're allowing a running QThread to be destructed. That's a common error since QThread is essentially broken by design. Sane C++ classes should be always destructible. QThread isn't. Thus you need a workaround.
You're not setting the minimum height of the contents widget as well.
You might wish to consider the use QtConcurrent::run instead of a dedicated thread. This is especially worthwhile when the operation you're undertaking is a one liner, more or less. I've shown both, the implementations are alternated between at runtime. Note that you need to add the concurrent module and CONFIG += c++11 to the project file.
Style bugs:
There's no reason to pass NULL for default-valued parameters that are already zero.
There's no reason to keep QObject members that have the lifetime of the parent object on the heap, if such members are constructed along with the parent object.
Just because Qt Creator comes with silly template files doesn't mean that you shouldn't be using a std::unique_ptr or QScopedPointer to hold the ui member. Naked pointers should almost never be members unless they're pointers to QObjects with parents.
As quite a bit of the code is missing, I can't really tell what else might be wrong. Below is a complete example.
// https://github.com/KubaO/stackoverflown/tree/master/questions/image-loader-24853687
#include <QtWidgets>
#include <QtConcurrent>
class Thread final : public QThread {
public:
~Thread() { quit(); wait(); }
};
class Loader : public QObject
{
Q_OBJECT
public:
explicit Loader(QObject *parent = nullptr) : QObject(parent) {}
Q_SIGNAL void imageLoaded(const QString &, const QImage &);
Q_SLOT void loadImage(const QString& fichier) {
QImage img(fichier);
if (! img.isNull()) emit imageLoaded(fichier, img);
}
};
class MainWindow : public QWidget
{
Q_OBJECT
Loader m_loader;
Thread m_loaderThread;
QGridLayout m_layout{this};
QPushButton m_open{"Open"};
QScrollArea m_view;
QWidget m_content;
int m_width{};
bool m_threadImpl = true;
Q_SIGNAL void loadImage(const QString &);
Q_SIGNAL void imageLoaded(const QString &, const QImage & img);
Q_SLOT void imageAvailable(const QString &, const QImage & img) {
int spacing = 20;
if (m_width) m_width += spacing;
auto lab = new QLabel(&m_content);
lab->setFixedSize(img.width(), img.height());
lab->setGeometry(m_width, 0, img.width(), img.height());
lab->setPixmap(QPixmap::fromImage(img));
lab->show();
m_width += img.width();
m_content.setMinimumWidth(m_width);
m_content.setMinimumHeight(qMax(m_content.minimumHeight(), img.height()));
}
Q_SLOT void open() {
auto dialog = new QFileDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
if (m_threadImpl)
connect(dialog, &QFileDialog::fileSelected, this, &MainWindow::loadImage);
else
connect(dialog, &QFileDialog::fileSelected, [this](const QString & fichier){
QtConcurrent::run([this, fichier]{
QImage img(fichier);
if (! img.isNull()) emit this->imageLoaded(fichier, img);
});
});
m_threadImpl = !m_threadImpl;
}
public:
explicit MainWindow(QWidget *parent = nullptr) : QWidget(parent) {
m_layout.addWidget(&m_open);
m_layout.addWidget(&m_view);
m_view.setWidget(&m_content);
m_loader.moveToThread(&m_loaderThread);
m_loaderThread.start();
connect(&m_open, &QPushButton::clicked, this, &MainWindow::open);
connect(this, &MainWindow::loadImage, &m_loader, &Loader::loadImage);
connect(this, &MainWindow::imageLoaded, this, &MainWindow::imageAvailable);
connect(&m_loader, &Loader::imageLoaded, this, &MainWindow::imageAvailable);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "main.moc"

glewInit with Qt5 returns Missing GL version

I have been trying to use Qt5 to give me an OpenGL context, which I believe it does, but when I try to call glewInit() from within the initializeGL function, the error returns back "Missing GL version," which I have been led to believe indicates that there is no valid context. The solution I saw was to call glewInit() from within initializeGL... but I'm already doing that.
I am setting the clear color and clearing to dark red to verify that gl calls are working, which they appear to be.
Any suggestions?
main.c
#define QT_NO_OPENGL_ES_2
#include <QApplication>
#include "glwidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GLWidget w;
w.show();
return a.exec();
}
glwidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <GL/glew.h>
#define QT_NO_OPENGL_ES_2
#include <QGLWidget>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QGLWidget *parent = 0);
~GLWidget();
QSize minimumSizeHint() const;
QSize sizeHint() const;
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
};
#endif // GLWIDGET_H
glwidget.cpp
#include "glwidget.h"
GLWidget::GLWidget(QGLWidget *parent) :
QGLWidget(parent)
{
}
GLWidget::~GLWidget() {}
QSize GLWidget::minimumSizeHint() const {
return QSize(640, 480);
}
QSize GLWidget::sizeHint() const {
return QSize(800, 600);
}
void GLWidget::initializeGL() {
GLenum err = glewInit();
if (GLEW_OK != err) {
printf("GLEW error: %s\n", glewGetErrorString(err));
} else {
printf("Glew loaded; using version %s\n", glewGetString(GLEW_VERSION));
}
glClearColor(0.2f, 0, 0, 1.0f);
}
void GLWidget::resizeGL(int w, int h) {
}
void GLWidget::paintGL() {
glClear( GL_COLOR_BUFFER_BIT );
}
Something tells me this is because of the QGLWidget's default QGLFormat using OpenGL version 1.0 (Looking through GLEW's change logs, it seems the earliest version they claim to fully support is 1.5) . Try instead to override the QGLWidget constructor that requires a QGLFormat and pass it an instance of QGLFormat that uses the version you are targeting.
The call to your widget should look something like:
QGLFormat format;
format.setVersion(3,3); // or whatever version you are targeting.
format.setDoubleBuffer(true);
GLWidget * widget = new GLWidget(format);

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