QML Camera size issue - qt

I am facing an issue with image size when I pass the image from QML to Qt to perform some processing.
I have a Camera element and a VideoOutput element inside a QML document and I have a class that takes the Camera image to perform the changes in C++. This class is registered to be used with QML: qmlRegisterType<processaImagem>("ProcessaImagemQml", 1, 0, "ProcessaImagem"); in main.cpp
Inside the processaImagem class I have a Q_PROPERTY called tamanhoImagem that holds the size of the image. The value of this property is defined inside the QML document camera.tamanhoImagem = Qt.size(cameraView.sourceRect.width, cameraView.sourceRect.height);
The problem is that the image size returned in QML is different than the same value passed to C++. In QML the result of console.log("Tamanho da imagem: " + camera.tamanhoImagem); is 320 x 240 and in C++ the result of qDebug() << p_tamanhoImagem; is 180 x 240.
This problem just occurs when I run this code on a smartphone; on a desktop it runs without this problem.
Code below:
Camera {
id: camera
property string caminhoPreview: ""
property size tamanhoImagem: Qt.size(0, 0);
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
imagemPreview.source = preview;
camera.caminhoPreview = preview;
camera.tamanhoImagem = Qt.size(cameraView.sourceRect.width, cameraView.sourceRect.height);
camera.stop();
console.log("Tamanho da imagem: " + camera.tamanhoImagem);
}
}
}
VideoOutput {
id: cameraView
visible: true
focus: visible
anchors.fill: parent
source: camera
orientation: camera.orientation
fillMode: VideoOutput.PreserveAspectFit
}
ProcessaImagem {
id: processaImagem
caminhoImagem: camera.caminhoPreview
tamanhoImagem: camera.tamanhoImagem
onCaminhoImagemChanged: {
ProvedorImagem.carregaImagem(processaImagem.carregaImagem());
}
}
processaimagem.h
class processaImagem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString caminhoImagem READ caminhoImagem WRITE setCaminhoImagem NOTIFY caminhoImagemChanged)
Q_PROPERTY(QSize tamanhoImagem READ tamanhoImagem WRITE setTamanhoImagem NOTIFY tamanhoImagemChanged)
public slots:
QImage carregaImagem();
public:
processaImagem(QObject *parent = 0);
QString caminhoImagem() const;
void setCaminhoImagem(const QString valor);
QSize tamanhoImagem() const;
void setTamanhoImagem(const QSize valor);
private:
QString p_caminhoImagem = "";
QSize p_tamanhoImagem = QSize(0, 0);
signals:
void caminhoImagemChanged();
void tamanhoImagemChanged();
};
processaimagem.cpp
processaImagem::processaImagem(QObject *parent)
{
}
QImage processaImagem::carregaImagem()
{
QUrl caminhoImagem(p_caminhoImagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem = imageProvider->requestImage(imageId, &p_tamanhoImagem, p_tamanhoImagem);
if(imagem.isNull())
{
qDebug() << "Erro ao carregar a imagem";
imagem = QImage();
}
else
{
qDebug() << "p_imagem size: ";
qDebug() << p_tamanhoImagem;
}
}
QString processaImagem::caminhoImagem() const
{
return p_caminhoImagem;
}
void processaImagem::setCaminhoImagem(const QString valor)
{
if (valor != p_caminhoImagem)
{
p_caminhoImagem = valor;
emit caminhoImagemChanged();
}
}
QSize processaImagem::tamanhoImagem() const
{
return p_tamanhoImagem;
}
void processaImagem::setTamanhoImagem(const QSize valor)
{
bool alterou = false;
if (valor.width() != p_tamanhoImagem.width())
{
p_tamanhoImagem.setWidth(valor.width());
alterou = true;
}
if (valor.height() != p_tamanhoImagem.height())
{
p_tamanhoImagem.setHeight(valor.height());
alterou = true;
}
if(alterou)
{
emit tamanhoImagemChanged();
}
}

Answering my own question:
In the method processaImagem just pass a empty QSize as parameter to the provider and it will return the image with it original size:
QImage processaImagem::carregaImagem()
{
QUrl caminhoImagem(p_caminhoImagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem = imageProvider->requestImage(imageId, &imageSize, imageSize);
if(imagem.isNull())
{
qDebug() << "Erro ao carregar a imagem";
imagem = QImage();
}
else
{
qDebug() << "p_imagem size: ";
qDebug() << p_tamanhoImagem;
}
}

Related

TableView does't update, but list into model is full

I am trying to update a table with data coming from an external process (into QML I lunch a CLI tool that returns a lot of strings and with that, I update the table). I am using TableView to show these data, and I wrote a Model class and a List class: the Model class extend QAbstractTableModel, indeed the list class extend QObject.
I am sure that the list is full (I print the contents with qDebug()), but the table is always empty! Can you help me?
I added some debug prints and I can see that the rowCount function of the model is called a lot of time and return the correct length of the list, but the data function is called only when index.row() is equal to zero! I don't understand why!
#ifndef PAYEELIST_H
#define PAYEELIST_H
#include <QObject>
#include <QList>
#include "payee.h"
class PayeeList : public QObject
{
Q_OBJECT
public:
explicit PayeeList(QObject *parent = nullptr);
QList<Payee> items() const;
// bool setItemAt (int index, const Payee &item);
void clear (void);
void append (const Payee& item);
signals:
void preItemAppended ();
void postItemAppended ();
void preItemRemoved (int index);
void postItemRemoved ();
//public slots:
// void appendItem ();
private:
QList<Payee> mItems;
};
#endif // PAYEELIST_H
#include "payeelist.h"
PayeeList::PayeeList(QObject *parent) : QObject(parent)
{
}
QList<Payee> PayeeList::items() const
{
return mItems;
}
void PayeeList::clear()
{
mItems.clear();
}
void PayeeList::append(const Payee &item)
{
emit preItemAppended();
mItems.append(item);
emit postItemAppended();
}
#ifndef PAYEEMODEL_H
#define PAYEEMODEL_H
#include <QAbstractTableModel>
#include "payeelist.h"
//class PayeeList;
class PayeeModel : public QAbstractTableModel
{
Q_OBJECT
Q_PROPERTY(PayeeList *list READ list WRITE setList)
public:
explicit PayeeModel(QObject *parent = nullptr);
enum
{
HeadingRole = Qt::UserRole + 1,
DataRole
};
enum
{
IdColumn = 0,
NameColumn,
TypeColumn
};
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
virtual QHash<int, QByteArray> roleNames() const override;
PayeeList *list (void) const;
void setList (PayeeList *list);
private:
PayeeList *mList;
};
#endif // PAYEEMODEL_H
#include "payeemodel.h"
PayeeModel::PayeeModel(QObject *parent)
: QAbstractTableModel(parent),
mList(nullptr)
{
}
int PayeeModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
if (parent.isValid() || !mList)
return 0;
qDebug() << "LIST SIZE:" << mList->items().size();
return mList->items().size() + 1;
}
int PayeeModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid() || !mList)
return 0;
return 3;
}
QVariant PayeeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || !mList)
return QVariant();
switch (role)
{
case DataRole:
{
qDebug() << "INDEX ROW:" << index.row();
if (index.row() > 0)
{
const Payee item = mList->items().at(index.row() - 1);
switch (index.column())
{
case IdColumn:
return QString::number(item.id());
break;
case NameColumn:
return QString(item.name());
break;
case TypeColumn:
return QString(item.type().name());
break;
}
}
else
{
switch (index.column())
{
case IdColumn:
return QString("Id");
break;
case NameColumn:
return QString("Name");
break;
case TypeColumn:
return QString("Type");
break;
}
}
}
break;
case HeadingRole:
if (index.row() == 0)
{
return true;
}
else
{
return false;
}
break;
default:
break;
}
return QVariant();
}
QHash<int, QByteArray> PayeeModel::roleNames() const
{
QHash<int, QByteArray> names;
names[HeadingRole] = "tableheading";
names[DataRole] = "tabledata";
return names;
}
PayeeList *PayeeModel::list (void) const
{
return mList;
}
void PayeeModel::setList (PayeeList *list)
{
beginResetModel();
if (mList)
{
mList->disconnect(this);
}
mList = list;
if (mList)
{
connect(mList, &PayeeList::preItemAppended, this, [=]()
{
const int index = mList->items().size();
beginInsertRows(QModelIndex(), index, index);
});
connect(mList, &PayeeList::postItemAppended, this, [=]()
{
endInsertRows();
});
}
endResetModel();
}
The QML file is:
import QtQuick 2.12
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import PlutoTool 1.0
Rectangle {
id: payeePage
Layout.fillWidth: true
property var title: "TITLE"
TableView {
columnSpacing: 1
rowSpacing: 1
anchors.fill: parent
clip: false
property var columnWidths: [50, (parent.width - 220), 150]
columnWidthProvider: function (column) { return columnWidths[column] }
model: PayeeModel {
list: lPayeeList
}
delegate: Rectangle {
implicitWidth: 200
implicitHeight: 30
border.color: "black"
border.width: 0
color: (tableheading == true) ? "#990033":"#EEEEEE"
Text {
text: model.tabledata
color: (tableheading == true) ? "#FFFFFF":"#000000"
font.bold: (tableheading == true) ? true : false
anchors.centerIn: parent
}
Component.onCompleted: {
console.log(model.tabledata);
}
}
}
}

Received Image from socket and display in Qml

I want to received image through using TCP socket and display in QMl window.
currently :I am able to receive .png image from socket. and : able to display the image from local disk in qml using image provider. but while integrating the both things i am facing the issue. how to call the socket's function.
tcpserver.h
class MyTcpServer : public QObject
{
Q_OBJECT
public:
explicit MyTcpServer(QObject *parent = 0);
signals:
public slots:
void newConnection();
void on_readyRead();
private:
QTcpServer *server;
};```
```
tcpserver.cpp
QByteArray array,array1;
MyTcpServer::MyTcpServer(QObject *parent) :
QObject(parent)
{server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()),
this, SLOT(newConnection()));
connect(server,SIGNAL(readyRead()),this,SLOT(readyRead()));
if(!server->listen(QHostAddress::Any, 9999))
{
qDebug() << "Server could not start";
}
else
{
qDebug() << "Server started!";
}
}
void MyTcpServer::newConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
if(socket)
{
connect(socket ,SIGNAL(readyRead()),this,SLOT(on_readyRead()));
socket->write("Hello client \r\n");
socket->flush();
socket->waitForBytesWritten(3000);
}
}
void MyTcpServer::on_readyRead()
{
QTcpSocket * server = dynamic_cast<QTcpSocket*>(sender());
qDebug()<<"reading..";
if(server)
{
qDebug()<<"Array size " << array.size() ;
array.append(server->readAll());
if(array.size()<230400)
{
qDebug()<<"Array size " << array.size() ;
}
else {
qDebug()<<"Array size else " << array.size() ;
cv::Mat img,img1;
cv::Size const frame_size(240,320);
img = cv::Mat(240,320, CV_8UC3,array.data());
qDebug()<<"Image type " <<img.type();
qDebug()<<"Array size " << array.size() ;
qDebug()<<"beforeImage size size " << img.dims;
cv::imshow("image display",img);
cv::waitKey(5000);
QImage imdisplay((uchar*)img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
}
}
}
//socket->close()
}
```
imageprovider.cpp
QImage QmlImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
printf("In request function ..\n");
MyTcpServer *m = new MyTcpServer();
m->newConnection();
printf("after connectrion....");
QImage image1= m->on_readyRead();
printf("after request....");
return image;
}
```
You should move MyTcpServer *m = new MyTcpServer(); to ImageProvider class constructor and m to class members, also create a signal in your MyTcpServer class and connect it to your ImageProvider updateImage slot.
P.S Maybe need to change updateImage from simple function to slot.
tcpserver.h
class MyTcpServer : public QObject
{
Q_OBJECT
public:
explicit MyTcpServer(QObject *parent = 0);
signals:
void newImageReceived(QImage);
.
.
.
tcpserver.cpp on_readyRead()
cv::imshow("image display",img);
cv::waitKey(5000);
QImage imdisplay((uchar*)img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
emit newImageReceived(imdisplay);
qmlimageprovider.cpp
QmlImageProvider::QmlImageProvider()
: QQuickImageProvider(QQuickImageProvider::Image)
{
m = new MyTcpServer();
connect(m, &MyTcpServer::newImageReceived, this, &QmlImageProvider::updateImage);
m->newConnection();
}
qmlimageprovider.h
class QmlImageProvider : public QQuickImageProvider
{
public:
QmlImageProvider();
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
public slots:
void updateImage(QImage new_image);
private:
QImage image;
MyTcpServer *m;
};

Testing Qt application with Qt Test

I have looked at the 5 Qt testing examples including the one about GUI events, but these examples are way too simple.
I want to test my program by launching it, simulating some clicks, and checking the value of instance variables that have been changed by those clicks.
I assume that this test below is illogical: a.exec() blocks the thread until the program is closed, and when the program is closed w has been deleted I think (or will be deleted later?).
So how to write system/GUI tests?
My test:
void LaunchProgramTest::LaunchProgramTestFunction() {
QApplication a(argc, argv);
MainWindow *w = new MainWindow();
w->show();
a.exec();
int testResult = w->myTestFunction();
qDebug() << testResult; //Prints big numbers like "-17891602" or "1753770528" as if testResult was not initialized
QVERIFY2(testResult == 3, "Incorrectly changed");
}
In mainWindow.h I declared a variable:
int testValue;
Mainwindow.cpp is the class for the main GUI of the program. In the constructor I added
testValue = 2;
Then in a function that is executed upon events I wrote
void MainWindow::on_actionTest_clicked() {
testValue = 3;
}
enter code hereSo)) you need to add QTest, add .pro
QT += testlib
and
#include <QTest>
I will show an example of my implementation for MousePress, the rest you can do yourself))
struct EventMK
{
int type;
QString m_widPath;
int _timer;
int width;
int height;
QPoint p;
QPoint g;
int button;
int buttons;
int modifiers;
int _key;
QString text;
void print(){
qDebug()<<"{ \n"
<<"type "<< type<<","<<"\n"
<<"Widget_Path "<< m_widPath<<","<<"\n"
<<"Timer "<< _timer<<","<<"\n"
<<"Width "<< width<<","<<"\n"
<<"Height "<< height<<","<<"\n"
<<"Pos_x "<< p.x()<<","<<"\n"
<<"Pos_y "<< p.y()<<","<<"\n"
<<"Global_x "<< g.x()<<","<<"\n"
<<"Global_y "<< g.y()<<","<<"\n"
<<"Button "<< button<<","<<"\n"
<<"Buttons "<< buttons<<","<<"\n"
<<"Modifiers "<< modifiers<<","<<"\n"
<<"Key "<< _key<<","<<"\n"
<<"Text "<< text<<"\n"
<<"}\n";
}
};
QWidget * _getWidget(EventMK ev)
{
QString wname = ev.m_widPath;
QStringList wpath = wname.split ( "/" );
return QWidgetUtils::getAWidget(&wpath);
}
void _postExecution(EventMK ev, QWidget *widget)
{
if (widget){
//set focus
QWidgetUtils::setFocusOnWidget(widget);
//end simulation
widget->setUpdatesEnabled ( true );
widget->update();
}
}
QPoint adaptedPosition(EventMK ev, QWidget *w)
{
if (w == nullptr)
return QPoint(ev.p.x(), ev.p.y());
int orig_w = ev.width;
int orig_h = ev.height;
int curr_w = w->width();
int curr_h = w->height();
int new_x = ev.p.x() * curr_w / orig_w;
int new_y = ev.p.y() * curr_h / orig_h;
return QPoint(new_x, new_y);
}
and function implementation
void executeMousePressEvent(EventMK ev)
{
QWidget* widget = _getWidget(ev);
if ( widget == nullptr )
{
qDebug()<<"error: "<<__LINE__<<__FUNCTION__;
return;
}
// _preExecutionWithMouseMove(ev, widget);
if (widget){
QTest::mousePress ( widget, (Qt::MouseButton)ev.button ,
(Qt::KeyboardModifier) ev.modifiers,
adaptedPosition(ev,widget));
}
_postExecution(ev, widget);
}
now left to fill struct EventMK , you need to populate it from MouseButtonPress events.
Here is my example
bool eventFilter(QObject *obj, QEvent *event)
{
///
/// process control
///
//window events
if (event->type() == QEvent::KeyPress)
{
handleKeyPressEvent(obj, event);
}
//mouse events
else if (event->type() == QEvent::MouseButtonPress)
{
handleMousePressEvent(obj, event);
}
else if (event->type() == QEvent::MouseButtonRelease)
{
handleMouseReleaseEvent(obj, event);
}
else if (event->type() == QEvent::MouseButtonDblClick)
{
handleMouseDoubleEvent(obj, event);
}
else if (event->type() == QEvent::Wheel)
{
handleWheelEvent(obj, event);
}
//keyboard events
else if (event->type() == QEvent::Close)
{
handleCloseEvent(obj, event);
}
///the event should continue to reach its goal...
return false;
}
and
void handleMousePressEvent(QObject *obj, QEvent *event)
{
QWidget *widget = isValidWidget(obj);
if (!widget){
return;
}
QMouseEvent *me = dynamic_cast< QMouseEvent*> ( event );
//create the event
if (widget != nullptr){
EventMK evkm;
evkm.type = QOE_MOUSE_PRESS; // set your type
evkm._timer = _timer.restart(); // add your QElapsedTimer
evkm.m_widPath = QWidgetUtils::getWidgetPath(widget);
evkm. width = widget->width();
evkm. height = widget->height();
QPoint p ( me->pos() );
QPoint g = widget->mapToGlobal ( p );
evkm. p = p;
evkm. g = g;
evkm. button = me->button();
evkm. buttons = me->buttons();
evkm. modifiers = me->modifiers();
evkm.print();
}
//send event if EventMK is valid
}
so, it turns out we can write a scenario and run what you wanted, thanks

QML Camera - take a Square photo

How can I take a photo using Camera in QML but with custom dimensions, like a square photo for example? I am trying to implement it with QQuickImageProvider but I am not understanding why it is not working.
QML code
Camera {
id: camera
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
manipulaImagem.imagem = preview;
previewImage.source = "image://ProvedorImagens/" + preview;
//previewImage.source = manipulaImagem.recortarFotoPerfil(preview, viewfinder.mapRectToSource(Qt.rect(viewfinder.x, viewfinder.y, viewfinder.width, viewfinder.height)));
}
}
}
Image {
id: previewImage
fillMode: Image.PreserveAspectFit
anchors.top: parent.top
width: parent.width
height: parent.width
}
I am trying to resolve this problem by 2 ways:
First:
QImage manipulaImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
QUrl caminhoImagem(id);
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem1(id);
if(imagem1.isNull())
{
qDebug() << "Erro";
}
else
{
qDebug() << "OK";
}
return imagem1;
}
I call this method from QML using a image provider: previewImage.source = "image://ProvedorImagens/" + preview;
In this function using QImage imagem1(id) or QImage imagem1(imageId), both return me a NULL image.
It returns me message: QML Image: Failed to get image from provider: image://provedorimagens/image://camera/preview_1
The other way is another function:
QImage manipulaImagem::recortarFotoPerfil(const QString &imagem)
{
QUrl caminhoImagem(imagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem1 = imageProvider->requestImage(imageId, &imageSize, imageSize);
imagem1 = imageProvider->requestImage(imageId, &imageSize, imageSize);
if(imagem1.isNull())
{
qDebug() << "Erro";
}
else
{
qDebug() << "OK";
}
return imagem1;
}
This function gets the image but when I return it I receive a message:
Error: Cannot assign QImage to QUrl
I call this function directly from QML:
previewImage.source = manipulaImagem.recortarFotoPerfil(preview);
Thanks for the help.
Answering my own question
Problem solved. Here is the solution step by step:
1 - Create a class that inherits from QQuickImageProvider and QObject and inside it create a Image member (QImage) that is the image to be provided.
class provedorImagem : public QObject, public QQuickImageProvider
Implement the virtual requestImage method. This is the method that will return the image to Qml
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
Create a method to load the provider’s image to return
void provedorImagem::carregaImagem(QImage imagemRecebida)
{
imagem = imagemRecebida;
}
Now set it as the engine image provider in the main.cpp file
provedorImagem *provedorImg = new provedorImagem;
engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);
2 - Create another class that inherits from QObject.
class processaImagem : public QObject
Inside this class you must implement a method that will get the image from camera provider, perform the image modifications and return the modified image.
PS: The p_caminhoImagem is a property that I created inside the processaImagem class that receives the camera preview path.
QImage processaImagem::carregaImagem()
{
QUrl caminhoImagem(p_caminhoImagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem = imageProvider->requestImage(imageId, &imageSize, imageSize);
if(imagem.isNull())
{
imagem = QImage();
}
else
{
//Perform the modifications
}
return imagem;
}
3 - Now is the main part. The image requestImage provider method must receive the modified image from the processaImagem class to provide it to QML. To do it the provider class pointer must be accessible to the QML file, so, in the main.cpp file just make the pointer available to QML as a property
engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);
and register the processaImagem class as a QML type
qmlRegisterType<processaImagem>("ProcessaImagemQml", 1, 0, "ProcessaImagem");
Now we link it inside the QML file
ProvedorImagem.carregaImagem(processaImagem.carregaImagem());
4 - It is done. Now just request the image from the provider:
imagemPreview.source = "image://provedor/imagemEditada_" + camera.numeroImagem.toString();
Here is the entire code:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "processaimagem.h"
#include "provedorimagem.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<processaImagem>("ProcessaImagemQml", 1, 0, "ProcessaImagem");
QQmlApplicationEngine engine;
provedorImagem *provedorImg = new provedorImagem;
engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);
engine.addImageProvider("provedor", provedorImg);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.3
import QtMultimedia 5.4
import ProcessaImagemQml 1.0
Window {
visible: true
width: 360
height: 640
maximumHeight: 640
minimumHeight: 640
maximumWidth: 360
minimumWidth: 360
title: "Camera Preview Test"
Rectangle {
id: principal
anchors.fill: parent
ProcessaImagem {
id: processaImagem
caminhoImagem: camera.caminhoPreview
caminhoSalvar: camera.caminhoSalvar
rectRecorte: camera.rectRecorte
tamanhoImagem: camera.tamanhoImagem
anguloOrientacaoCamera: camera.orientation
posicaoCamera: camera.position
onCaminhoImagemChanged: {
rectRecorte = cameraView.mapRectToSource(Qt.rect(cameraView.x, cameraView.y, cameraView.width, cameraView.height));
tamanhoImagem = Qt.size(cameraView.sourceRect.width, cameraView.sourceRect.height);
ProvedorImagem.carregaImagem(processaImagem.carregaImagem());
}
onCaminhoSalvarChanged: {
removeImagemSalva();
}
}
Rectangle {
id: cameraRectangle
width: parent.width
height: parent.width
anchors.top: parent.top
color: "lightGrey"
visible: true
Camera {
id: camera
property string caminhoPreview: ""
property string caminhoSalvar: ""
property int numeroImagem: 0
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
camera.caminhoPreview = preview;
camera.stop();
imagemPreview.source = "image://provedor/imagemEditada_" + camera.numeroImagem.toString();
camera.numeroImagem = camera.numeroImagem + 1;
imagemPreviewRectangle.visible = true;
cameraRectangle.visible = false;
}
onImageSaved: {
camera.caminhoSalvar = path;
}
}
}
VideoOutput {
id: cameraView
visible: true
focus: visible
anchors.fill: parent
source: camera
orientation: camera.orientation
fillMode: VideoOutput.PreserveAspectCrop
}
}
Rectangle {
id: imagemPreviewRectangle
width: parent.width
height: parent.width
anchors.top: parent.top
color: "lightGrey"
visible: false
Image {
id: imagemPreview
fillMode: Image.PreserveAspectFit
anchors.fill: parent
}
}
Rectangle {
id: controleRectangle
width: parent.width
height: parent.height - cameraRectangle.height
color: "grey"
anchors.top: cameraRectangle.bottom
Button {
id: tirarFotoButton
text: "Tirar foto"
anchors.left: parent.left
anchors.top: parent.top
onClicked: {
camera.imageCapture.capture();
}
}
Button {
id: novaFotoButton
text: "Tirar nova foto"
anchors.right: parent.right
anchors.top: parent.top
onClicked: {
camera.start();
imagemPreviewRectangle.visible = false;
cameraRectangle.visible = true;
}
}
}
}
}
processaimagem.h
#ifndef PROCESSAIMAGEM_H
#define PROCESSAIMAGEM_H
#include <QObject>
#include <QImage>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQuickImageProvider>
#include <QFile>
#include "provedorimagem.h"
class processaImagem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString caminhoImagem READ caminhoImagem WRITE setCaminhoImagem NOTIFY caminhoImagemChanged)
Q_PROPERTY(QString caminhoSalvar READ caminhoSalvar WRITE setCaminhoSalvar NOTIFY caminhoSalvarChanged)
Q_PROPERTY(QRect rectRecorte READ rectRecorte WRITE setRectRecorte NOTIFY rectRecorteChanged)
Q_PROPERTY(QSize tamanhoImagem READ tamanhoImagem WRITE setTamanhoImagem NOTIFY tamanhoImagemChanged)
Q_PROPERTY(int anguloOrientacaoCamera READ anguloOrientacaoCamera WRITE setAnguloOrientacaoCamera NOTIFY anguloOrientacaoCameraChanged)
Q_PROPERTY(int posicaoCamera READ posicaoCamera WRITE setPosicaoCamera NOTIFY posicaoCameraChanged)
public slots:
QImage carregaImagem();
void removeImagemSalva();
public:
processaImagem(QObject *parent = 0);
QString caminhoImagem() const;
void setCaminhoImagem(const QString valor);
QString caminhoSalvar() const;
void setCaminhoSalvar(const QString valor);
QRect rectRecorte() const;
void setRectRecorte(const QRect valor);
QSize tamanhoImagem() const;
void setTamanhoImagem(const QSize valor);
int anguloOrientacaoCamera() const;
void setAnguloOrientacaoCamera(const int valor);
int posicaoCamera() const;
void setPosicaoCamera(const int valor);
private:
QString p_caminhoImagem = "";
QString p_caminhoSalvar = "";
QRect p_rectRecorte = QRect(0, 0, 0, 0);
QSize p_tamanhoImagem = QSize(0, 0);
int p_anguloOrientacaoCamera = 0;
int p_posicaoCamera = 0;
signals:
void caminhoImagemChanged();
void caminhoSalvarChanged();
void rectRecorteChanged();
void tamanhoImagemChanged();
void anguloOrientacaoCameraChanged();
void posicaoCameraChanged();
};
#endif // PROCESSAIMAGEM_H
processaimagem.cpp
#include "processaimagem.h"
#include <QDebug>
processaImagem::processaImagem(QObject *parent)
{
}
QImage processaImagem::carregaImagem()
{
QUrl caminhoImagem(p_caminhoImagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem = imageProvider->requestImage(imageId, &imageSize, imageSize);
if(imagem.isNull())
{
qDebug() << "Erro ao carregar a imagem";
imagem = QImage();
}
else
{
if((p_anguloOrientacaoCamera == 90) || (p_anguloOrientacaoCamera == 270))
{
int larguraImagem = p_tamanhoImagem.width();
int alturaImagem = p_tamanhoImagem.height();
p_tamanhoImagem.setWidth(alturaImagem);
p_tamanhoImagem.setHeight(larguraImagem);
int recorteX = p_rectRecorte.x();
int recorteY = p_rectRecorte.y();
int recorteLargura = p_rectRecorte.width();
int recorteAltura = p_rectRecorte.height();
p_rectRecorte.setRect(recorteY, recorteX, recorteAltura, recorteLargura);
if(imagem.size().width() > imagem.size().height())
{
QTransform rotacao;
rotacao.rotate(360 - p_anguloOrientacaoCamera);
imagem = imagem.transformed(rotacao);
qDebug() << "Rodou";
}
}
if(imagem.width() != p_tamanhoImagem.width())
{
imagem = imagem.scaled(p_tamanhoImagem);
}
imagem = imagem.copy(p_rectRecorte);
}
return imagem;
}
void processaImagem::removeImagemSalva()
{
QFile::remove(p_caminhoSalvar);
}
QString processaImagem::caminhoImagem() const
{
return p_caminhoImagem;
}
void processaImagem::setCaminhoImagem(const QString valor)
{
if (valor != p_caminhoImagem)
{
p_caminhoImagem = valor;
emit caminhoImagemChanged();
}
}
QString processaImagem::caminhoSalvar() const
{
return p_caminhoSalvar;
}
void processaImagem::setCaminhoSalvar(const QString valor)
{
if (valor != p_caminhoSalvar)
{
p_caminhoSalvar = valor;
emit caminhoSalvarChanged();
}
}
QRect processaImagem::rectRecorte() const
{
return p_rectRecorte;
}
void processaImagem::setRectRecorte(const QRect valor)
{
bool alterou = false;
if (valor.x() != p_rectRecorte.x())
{
p_rectRecorte.setX(valor.x());
alterou = true;
}
if (valor.y() != p_rectRecorte.y())
{
p_rectRecorte.setY(valor.y());
alterou = true;
}
if (valor.width() != p_rectRecorte.width())
{
p_rectRecorte.setWidth(valor.width());
alterou = true;
}
if (valor.height() != p_rectRecorte.height())
{
p_rectRecorte.setHeight(valor.height());
alterou = true;
}
if(alterou)
{
emit rectRecorteChanged();
}
}
QSize processaImagem::tamanhoImagem() const
{
return p_tamanhoImagem;
}
void processaImagem::setTamanhoImagem(const QSize valor)
{
bool alterou = false;
if (valor.width() != p_tamanhoImagem.width())
{
p_tamanhoImagem.setWidth(valor.width());
alterou = true;
}
if (valor.height() != p_tamanhoImagem.height())
{
p_tamanhoImagem.setHeight(valor.height());
alterou = true;
}
if(alterou)
{
emit tamanhoImagemChanged();
}
}
int processaImagem::anguloOrientacaoCamera() const
{
return p_anguloOrientacaoCamera;
}
void processaImagem::setAnguloOrientacaoCamera(const int valor)
{
if (valor != p_anguloOrientacaoCamera)
{
p_anguloOrientacaoCamera = valor;
emit anguloOrientacaoCameraChanged();
}
}
int processaImagem::posicaoCamera() const
{
return p_posicaoCamera;
}
void processaImagem::setPosicaoCamera(const int valor)
{
if (valor != p_posicaoCamera)
{
p_posicaoCamera = valor;
emit posicaoCameraChanged();
}
}
provedorimagem.h
#ifndef PROVEDORIMAGEM_H
#define PROVEDORIMAGEM_H
#include <QObject>
#include <QImage>
#include <QQuickImageProvider>
class provedorImagem : public QObject, public QQuickImageProvider
{
Q_OBJECT
public:
provedorImagem();
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
public slots:
void carregaImagem(QImage imagemRecebida);
private:
QImage imagem;
};
#endif // PROVEDORIMAGEM_H
provedorimagem.cpp
#include "provedorimagem.h"
#include <QDebug>
provedorImagem::provedorImagem() : QQuickImageProvider(QQuickImageProvider::Image)
{
}
QImage provedorImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
if(imagem.isNull())
{
qDebug() << "Erro ao prover a imagem";
}
return imagem;
}
void provedorImagem::carregaImagem(QImage imagemRecebida)
{
imagem = imagemRecebida;
}

Pass QImage to QML

I am trying to pass a QImage to QML. Could someone help me? The code is below.
The problem is that all my attempts to make the image available for the image provider fail. I have tried using a Q_PROPERTY and a QImage member inside the class, but my provider always returns a null image when I try to access it to return.
How can I make the QImage available for the provider?
QML
Camera {
id: camera
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
manipulaImagem.imagem = preview;
previewImage.source = manipulaImagem.recortarFotoPerfil(preview, viewfinder.mapRectToSource(Qt.rect(viewfinder.x, viewfinder.y, viewfinder.width, viewfinder.height)));
}
}
}
Image {
id: previewImage
fillMode: Image.PreserveAspectFit
anchors.top: parent.top
width: parent.width
height: parent.width
}
CPP
QImage manipulaImagem::recortarFotoPerfil(const QString &imagem, QRect rectRecorte)
{
QUrl caminhoImagem(imagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem1 = imageProvider->requestImage(imageId, &imageSize, imageSize);
imagem1 = imageProvider->requestImage(imageId, &imageSize, imageSize);
return imagem1;
}
When I use this I receive the following message:
Error: Cannot assign QImage to QUrl
I did not find anything to help me to solve this. How can I do that?
I have tried a different approach using the image provider as suggested by the links, but it still not working
Here is the code
.h
#ifndef MANIPULAIMAGEM_H
#define MANIPULAIMAGEM_H
#include <QObject>
#include <QImage>
#include <QQuickImageProvider>
#include <QQmlEngine>
#include <QQmlContext>
class manipulaImagem : public QObject, public QQuickImageProvider
{
Q_OBJECT
public slots:
QString recortarFotoPerfil(const QString &imagem, QRect rectRecorte);
public:
manipulaImagem(QObject *parent = 0);
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
private:
void alocaImagem(const QString &imagem, QRect rectRecorte);
QImage imagemEditada;
};
#endif // MANIPULAIMAGEM_H
.cpp
#include "manipulaimagem.h"
#include <QDebug>
manipulaImagem::manipulaImagem(QObject *parent) : QQuickImageProvider(QQmlImageProviderBase::Image)
{
}
QImage manipulaImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
if(imagemEditada.isNull())
{
qDebug() << "Request image: (image is null)";
}
else
{
qDebug() << "Request image: image is OK";
}
return imagemEditada;
}
void manipulaImagem::alocaImagem(const QString &imagem, QRect rectRecorte)
{
QUrl caminhoImagem(imagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
imagemEditada = imageProvider->requestImage(imageId, &imageSize, imageSize);
if(imagemEditada.isNull())
{
qDebug() << "Loading image failed";
}
else
{
qDebug() << "Loading image OK";
}
}
QString manipulaImagem::recortarFotoPerfil(const QString &imagem, QRect rectRecorte)
{
this->alocaImagem(imagem, rectRecorte);
QString a = "image://ProvedorImagens/imagemEditada";
if(imagemEditada.isNull())
{
qDebug() << "Imagem is null";
}
else
{
qDebug() << "Imagem is loaded";
}
return a;
}
.qml
ManipulaImagem {
id: manipulaImagem
}
Camera {
id: camera
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
previewImage.source = manipulaImagem.recortarFotoPerfil(preview, viewfinder.mapRectToSource(Qt.rect(viewfinder.x, viewfinder.y, viewfinder.width, viewfinder.height)));
}
}
}
Rectangle {
id: previewRectangle
visible: false
anchors.fill: parent
Image {
id: previewImage
fillMode: Image.PreserveAspectFit
anchors.top: parent.top
width: parent.width
height: parent.width
}
The output of this code is:
Loading image OK
Imagem is loaded
Request image: (image is null)
QML Image: Failed to get image from provider: image://provedorimagens/imagemEditada
What happens is that when I call the functions the image is not null, but when I try to return the QImage using the provider it cant return the image. I dont know why but for the image provider the image is null.
How could I solve that?
Answering my own question
Problem solved. Here is the solution step by step:
1 - Create a class that inherits from QQuickImageProvider and QObject and inside it create a Image member (QImage) that is the image to be provided.
class provedorImagem : public QObject, public QQuickImageProvider
Implement the virtual requestImage method. This is the method that will return the image to Qml
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
Create a method to load the provider’s image to return
void provedorImagem::carregaImagem(QImage imagemRecebida)
{
imagem = imagemRecebida;
}
Now set it as the engine image provider in the main.cpp file
provedorImagem *provedorImg = new provedorImagem;
engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);
2 - Create another class that inherits from QObject.
class processaImagem : public QObject
Inside this class you must implement a method that will get the image from camera provider, perform the image modifications and return the modified image.
PS: The p_caminhoImagem is a property that I created inside the processaImagem class that receives the camera preview path.
QImage processaImagem::carregaImagem()
{
QUrl caminhoImagem(p_caminhoImagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem = imageProvider->requestImage(imageId, &imageSize, imageSize);
if(imagem.isNull())
{
imagem = QImage();
}
else
{
//Perform the modifications
}
return imagem;
}
3 - Now is the main part. The image requestImage provider method must receive the modified image from the processaImagem class to provide it to QML. To do it the provider class pointer must be accessible to the QML file, so, in the main.cpp file just make the pointer available to QML as a property
engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);
and register the processaImagem class as a QML type
qmlRegisterType<processaImagem>("ProcessaImagemQml", 1, 0, "ProcessaImagem");
Now we link it inside the QML file
ProvedorImagem.carregaImagem(processaImagem.carregaImagem());
4 - It is done. Now just request the image from the provider:
imagemPreview.source = "image://provedor/imagemEditada_" + camera.numeroImagem.toString();
Here is the entire code:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "processaimagem.h"
#include "provedorimagem.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<processaImagem>("ProcessaImagemQml", 1, 0, "ProcessaImagem");
QQmlApplicationEngine engine;
provedorImagem *provedorImg = new provedorImagem;
engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);
engine.addImageProvider("provedor", provedorImg);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.3
import QtMultimedia 5.4
import ProcessaImagemQml 1.0
Window {
visible: true
width: 360
height: 640
maximumHeight: 640
minimumHeight: 640
maximumWidth: 360
minimumWidth: 360
title: "Camera Preview Test"
Rectangle {
id: principal
anchors.fill: parent
ProcessaImagem {
id: processaImagem
caminhoImagem: camera.caminhoPreview
caminhoSalvar: camera.caminhoSalvar
rectRecorte: camera.rectRecorte
tamanhoImagem: camera.tamanhoImagem
anguloOrientacaoCamera: camera.orientation
posicaoCamera: camera.position
onCaminhoImagemChanged: {
rectRecorte = cameraView.mapRectToSource(Qt.rect(cameraView.x, cameraView.y, cameraView.width, cameraView.height));
tamanhoImagem = Qt.size(cameraView.sourceRect.width, cameraView.sourceRect.height);
ProvedorImagem.carregaImagem(processaImagem.carregaImagem());
}
onCaminhoSalvarChanged: {
removeImagemSalva();
}
}
Rectangle {
id: cameraRectangle
width: parent.width
height: parent.width
anchors.top: parent.top
color: "lightGrey"
visible: true
Camera {
id: camera
property string caminhoPreview: ""
property string caminhoSalvar: ""
property int numeroImagem: 0
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
camera.caminhoPreview = preview;
camera.stop();
imagemPreview.source = "image://provedor/imagemEditada_" + camera.numeroImagem.toString();
camera.numeroImagem = camera.numeroImagem + 1;
imagemPreviewRectangle.visible = true;
cameraRectangle.visible = false;
}
onImageSaved: {
camera.caminhoSalvar = path;
}
}
}
VideoOutput {
id: cameraView
visible: true
focus: visible
anchors.fill: parent
source: camera
orientation: camera.orientation
fillMode: VideoOutput.PreserveAspectCrop
}
}
Rectangle {
id: imagemPreviewRectangle
width: parent.width
height: parent.width
anchors.top: parent.top
color: "lightGrey"
visible: false
Image {
id: imagemPreview
fillMode: Image.PreserveAspectFit
anchors.fill: parent
}
}
Rectangle {
id: controleRectangle
width: parent.width
height: parent.height - cameraRectangle.height
color: "grey"
anchors.top: cameraRectangle.bottom
Button {
id: tirarFotoButton
text: "Tirar foto"
anchors.left: parent.left
anchors.top: parent.top
onClicked: {
camera.imageCapture.capture();
}
}
Button {
id: novaFotoButton
text: "Tirar nova foto"
anchors.right: parent.right
anchors.top: parent.top
onClicked: {
camera.start();
imagemPreviewRectangle.visible = false;
cameraRectangle.visible = true;
}
}
}
}
}
processaimagem.h
#ifndef PROCESSAIMAGEM_H
#define PROCESSAIMAGEM_H
#include <QObject>
#include <QImage>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQuickImageProvider>
#include <QFile>
#include "provedorimagem.h"
class processaImagem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString caminhoImagem READ caminhoImagem WRITE setCaminhoImagem NOTIFY caminhoImagemChanged)
Q_PROPERTY(QString caminhoSalvar READ caminhoSalvar WRITE setCaminhoSalvar NOTIFY caminhoSalvarChanged)
Q_PROPERTY(QRect rectRecorte READ rectRecorte WRITE setRectRecorte NOTIFY rectRecorteChanged)
Q_PROPERTY(QSize tamanhoImagem READ tamanhoImagem WRITE setTamanhoImagem NOTIFY tamanhoImagemChanged)
Q_PROPERTY(int anguloOrientacaoCamera READ anguloOrientacaoCamera WRITE setAnguloOrientacaoCamera NOTIFY anguloOrientacaoCameraChanged)
Q_PROPERTY(int posicaoCamera READ posicaoCamera WRITE setPosicaoCamera NOTIFY posicaoCameraChanged)
public slots:
QImage carregaImagem();
void removeImagemSalva();
public:
processaImagem(QObject *parent = 0);
QString caminhoImagem() const;
void setCaminhoImagem(const QString valor);
QString caminhoSalvar() const;
void setCaminhoSalvar(const QString valor);
QRect rectRecorte() const;
void setRectRecorte(const QRect valor);
QSize tamanhoImagem() const;
void setTamanhoImagem(const QSize valor);
int anguloOrientacaoCamera() const;
void setAnguloOrientacaoCamera(const int valor);
int posicaoCamera() const;
void setPosicaoCamera(const int valor);
private:
QString p_caminhoImagem = "";
QString p_caminhoSalvar = "";
QRect p_rectRecorte = QRect(0, 0, 0, 0);
QSize p_tamanhoImagem = QSize(0, 0);
int p_anguloOrientacaoCamera = 0;
int p_posicaoCamera = 0;
signals:
void caminhoImagemChanged();
void caminhoSalvarChanged();
void rectRecorteChanged();
void tamanhoImagemChanged();
void anguloOrientacaoCameraChanged();
void posicaoCameraChanged();
};
#endif // PROCESSAIMAGEM_H
processaimagem.cpp
#include "processaimagem.h"
#include <QDebug>
processaImagem::processaImagem(QObject *parent)
{
}
QImage processaImagem::carregaImagem()
{
QUrl caminhoImagem(p_caminhoImagem);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
QSize imageSize;
QString imageId = caminhoImagem.path().remove(0, 1);
QImage imagem = imageProvider->requestImage(imageId, &imageSize, imageSize);
if(imagem.isNull())
{
qDebug() << "Erro ao carregar a imagem";
imagem = QImage();
}
else
{
if((p_anguloOrientacaoCamera == 90) || (p_anguloOrientacaoCamera == 270))
{
int larguraImagem = p_tamanhoImagem.width();
int alturaImagem = p_tamanhoImagem.height();
p_tamanhoImagem.setWidth(alturaImagem);
p_tamanhoImagem.setHeight(larguraImagem);
int recorteX = p_rectRecorte.x();
int recorteY = p_rectRecorte.y();
int recorteLargura = p_rectRecorte.width();
int recorteAltura = p_rectRecorte.height();
p_rectRecorte.setRect(recorteY, recorteX, recorteAltura, recorteLargura);
if(imagem.size().width() > imagem.size().height())
{
QTransform rotacao;
rotacao.rotate(360 - p_anguloOrientacaoCamera);
imagem = imagem.transformed(rotacao);
qDebug() << "Rodou";
}
}
if(imagem.width() != p_tamanhoImagem.width())
{
imagem = imagem.scaled(p_tamanhoImagem);
}
imagem = imagem.copy(p_rectRecorte);
}
return imagem;
}
void processaImagem::removeImagemSalva()
{
QFile::remove(p_caminhoSalvar);
}
QString processaImagem::caminhoImagem() const
{
return p_caminhoImagem;
}
void processaImagem::setCaminhoImagem(const QString valor)
{
if (valor != p_caminhoImagem)
{
p_caminhoImagem = valor;
emit caminhoImagemChanged();
}
}
QString processaImagem::caminhoSalvar() const
{
return p_caminhoSalvar;
}
void processaImagem::setCaminhoSalvar(const QString valor)
{
if (valor != p_caminhoSalvar)
{
p_caminhoSalvar = valor;
emit caminhoSalvarChanged();
}
}
QRect processaImagem::rectRecorte() const
{
return p_rectRecorte;
}
void processaImagem::setRectRecorte(const QRect valor)
{
bool alterou = false;
if (valor.x() != p_rectRecorte.x())
{
p_rectRecorte.setX(valor.x());
alterou = true;
}
if (valor.y() != p_rectRecorte.y())
{
p_rectRecorte.setY(valor.y());
alterou = true;
}
if (valor.width() != p_rectRecorte.width())
{
p_rectRecorte.setWidth(valor.width());
alterou = true;
}
if (valor.height() != p_rectRecorte.height())
{
p_rectRecorte.setHeight(valor.height());
alterou = true;
}
if(alterou)
{
emit rectRecorteChanged();
}
}
QSize processaImagem::tamanhoImagem() const
{
return p_tamanhoImagem;
}
void processaImagem::setTamanhoImagem(const QSize valor)
{
bool alterou = false;
if (valor.width() != p_tamanhoImagem.width())
{
p_tamanhoImagem.setWidth(valor.width());
alterou = true;
}
if (valor.height() != p_tamanhoImagem.height())
{
p_tamanhoImagem.setHeight(valor.height());
alterou = true;
}
if(alterou)
{
emit tamanhoImagemChanged();
}
}
int processaImagem::anguloOrientacaoCamera() const
{
return p_anguloOrientacaoCamera;
}
void processaImagem::setAnguloOrientacaoCamera(const int valor)
{
if (valor != p_anguloOrientacaoCamera)
{
p_anguloOrientacaoCamera = valor;
emit anguloOrientacaoCameraChanged();
}
}
int processaImagem::posicaoCamera() const
{
return p_posicaoCamera;
}
void processaImagem::setPosicaoCamera(const int valor)
{
if (valor != p_posicaoCamera)
{
p_posicaoCamera = valor;
emit posicaoCameraChanged();
}
}
provedorimagem.h
#ifndef PROVEDORIMAGEM_H
#define PROVEDORIMAGEM_H
#include <QObject>
#include <QImage>
#include <QQuickImageProvider>
class provedorImagem : public QObject, public QQuickImageProvider
{
Q_OBJECT
public:
provedorImagem();
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
public slots:
void carregaImagem(QImage imagemRecebida);
private:
QImage imagem;
};
#endif // PROVEDORIMAGEM_H
provedorimagem.cpp
#include "provedorimagem.h"
#include <QDebug>
provedorImagem::provedorImagem() : QQuickImageProvider(QQuickImageProvider::Image)
{
}
QImage provedorImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
if(imagem.isNull())
{
qDebug() << "Erro ao prover a imagem";
}
return imagem;
}
void provedorImagem::carregaImagem(QImage imagemRecebida)
{
imagem = imagemRecebida;
}
Here's my code for converting a QImage to a QUrl. Once it's a QUrl you can easily pass it to QML:
QUrl imageToUrl(const QImage& image)
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "png");
QString base64 = QString::fromUtf8(byteArray.toBase64());
return QString("data:image/png;base64,") + base64;
}

Resources