Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [SOLVED] QML Camera - take a Square photo
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QML Camera - take a Square photo

Scheduled Pinned Locked Moved QML and Qt Quick
26 Posts 2 Posters 9.4k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • guidupasG guidupas

    @p3c0 No. So I cant resize the resolution directly from the camera. But now I will crop the image and I am facing a now problem: how can I pass the cropped image from C++ to QML?

    Thanks for the help.

    p3c0P Offline
    p3c0P Offline
    p3c0
    Moderators
    wrote on last edited by
    #6

    @guidupas AFAIK you can't directly. Use QQuickImageProvider and do cropping inside requestPixmap function and return the updated image or create you own item by subclassing QQuickPaintedItem then override paint function and draw that updated image.

    157

    1 Reply Last reply
    0
    • guidupasG Offline
      guidupasG Offline
      guidupas
      wrote on last edited by
      #7

      @p3c0 Hi. Could you help me with a little piece of code. I am facing some difficulties to implement that.

      Thanks a lot.

      Att.
      Guilherme Cortada Dupas

      p3c0P 1 Reply Last reply
      0
      • guidupasG guidupas

        @p3c0 Hi. Could you help me with a little piece of code. I am facing some difficulties to implement that.

        Thanks a lot.

        p3c0P Offline
        p3c0P Offline
        p3c0
        Moderators
        wrote on last edited by
        #8

        @guidupas The documentation explains the examples.
        QQuickPaintedItem

        • register the class
        • add functions to pass the image from QML
        • call update to repaint with new image

        QQuickImageProvider

        • No need to make a plugin for QQuickImageProvider
        • Make sure the image provider class gets the updated image
        • Need to reload the the Image url for updates to reflect

        I think subclassing QQuickPaintedItem would be a better option.

        157

        1 Reply Last reply
        0
        • guidupasG Offline
          guidupasG Offline
          guidupas
          wrote on last edited by guidupas
          #9

          Hi @p3c0 . I am trying to implement it with QQuickImageProvider but I am not understanding why it is not working. My code is below. If you could help me.

          caminhoimagens.h

          #ifndef MANIPULAIMAGEM_H
          #define MANIPULAIMAGEM_H
          
          #include <QObject>
          #include <QImage>
          #include <QQuickImageProvider>
          
          class manipulaImagem : public QObject, public QQuickImageProvider
          {
              Q_OBJECT
          
              Q_PROPERTY(QString imagem READ imagem WRITE setImagem NOTIFY imagemChanged)
          
          public:
              manipulaImagem();
          
              QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
          
              QString imagem() const;
              void setImagem(const QString &imagem_caminho);
          
          private:
              QString p_imagem;
          
          signals:
              void imagemChanged();
          };
          
          #endif // MANIPULAIMAGEM_H
          

          manipulaimagem.cpp

          #include "manipulaimagem.h"
          
          #include <QDebug>
          
          manipulaImagem::manipulaImagem() : QQuickImageProvider(QQuickImageProvider::Image)
          {
          
          }
          
          QImage manipulaImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
          {
              qDebug() << p_imagem;
          
              QImage imagemr(p_imagem);
          
              return imagemr;
          }
          
          QString manipulaImagem::imagem() const
          {
              return p_imagem;
          }
          
          void manipulaImagem::setImagem(const QString imagem_caminho)
          {
              if (imagem_caminho != p_imagem) {
                  p_imagem = imagem_caminho;
                  emit imagemChanged();
              }
          }
          

          main.cpp

          #include <QGuiApplication>
          #include <QQmlApplicationEngine>
          
          #include <QtQml>
          
          #include "manipulaxml.h"
          #include "caminhoimagens.h"
          #include "manipulaimagem.h"
          
          int main(int argc, char *argv[])
          {
              QGuiApplication app(argc, argv);
          
              qmlRegisterType<manipulaXml>("ManipXML", 1, 0, "ManipulaXML");
              qmlRegisterType<caminhoImagens>("PathImagens", 1, 0, "CaminhoImagens");
              qmlRegisterType<manipulaImagem>("ManipImagem", 1, 0, "ManipulaImagem");
          
              manipulaImagem *forneceImagem = new manipulaImagem();
              QQmlApplicationEngine engine;
              engine.addImageProvider("provedorImagem", forneceImagem);
              engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
          
              return app.exec();
          }
          

          QML

          Camera {
                          id: camera
          
                          captureMode: Camera.CaptureStillImage
          
                          imageCapture {
                              onImageCaptured: {
                                  manipulaImagem.imagem = preview.toString();
          
                                  console.log(preview.toString());
          
                                  previewImage.source = "image://provedorImagem/fotoPerfil"
                              }
                          }
                      }
          
                      VideoOutput {
                          id: viewfinder
                          
                          visible: true
          
                          focus: visible
          
                          anchors.top: parent.top
          
                          width: parent.width
                          height: parent.width
          
                          source: camera
                          
                          fillMode: VideoOutput.PreserveAspectCrop
                }
          
          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 response for this code is:
          qml: image://camera/preview_1
          ""
          QFSFileEngine::open: No file name specified
          qrc:/CriarPerfil.qml:983:9: QML Image: Failed to get image from provider: image://provedorimagem/fotoPerfil

          Att.
          Guilherme Cortada Dupas

          p3c0P 1 Reply Last reply
          0
          • guidupasG guidupas

            Hi @p3c0 . I am trying to implement it with QQuickImageProvider but I am not understanding why it is not working. My code is below. If you could help me.

            caminhoimagens.h

            #ifndef MANIPULAIMAGEM_H
            #define MANIPULAIMAGEM_H
            
            #include <QObject>
            #include <QImage>
            #include <QQuickImageProvider>
            
            class manipulaImagem : public QObject, public QQuickImageProvider
            {
                Q_OBJECT
            
                Q_PROPERTY(QString imagem READ imagem WRITE setImagem NOTIFY imagemChanged)
            
            public:
                manipulaImagem();
            
                QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
            
                QString imagem() const;
                void setImagem(const QString &imagem_caminho);
            
            private:
                QString p_imagem;
            
            signals:
                void imagemChanged();
            };
            
            #endif // MANIPULAIMAGEM_H
            

            manipulaimagem.cpp

            #include "manipulaimagem.h"
            
            #include <QDebug>
            
            manipulaImagem::manipulaImagem() : QQuickImageProvider(QQuickImageProvider::Image)
            {
            
            }
            
            QImage manipulaImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
            {
                qDebug() << p_imagem;
            
                QImage imagemr(p_imagem);
            
                return imagemr;
            }
            
            QString manipulaImagem::imagem() const
            {
                return p_imagem;
            }
            
            void manipulaImagem::setImagem(const QString imagem_caminho)
            {
                if (imagem_caminho != p_imagem) {
                    p_imagem = imagem_caminho;
                    emit imagemChanged();
                }
            }
            

            main.cpp

            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            
            #include <QtQml>
            
            #include "manipulaxml.h"
            #include "caminhoimagens.h"
            #include "manipulaimagem.h"
            
            int main(int argc, char *argv[])
            {
                QGuiApplication app(argc, argv);
            
                qmlRegisterType<manipulaXml>("ManipXML", 1, 0, "ManipulaXML");
                qmlRegisterType<caminhoImagens>("PathImagens", 1, 0, "CaminhoImagens");
                qmlRegisterType<manipulaImagem>("ManipImagem", 1, 0, "ManipulaImagem");
            
                manipulaImagem *forneceImagem = new manipulaImagem();
                QQmlApplicationEngine engine;
                engine.addImageProvider("provedorImagem", forneceImagem);
                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
            
                return app.exec();
            }
            

            QML

            Camera {
                            id: camera
            
                            captureMode: Camera.CaptureStillImage
            
                            imageCapture {
                                onImageCaptured: {
                                    manipulaImagem.imagem = preview.toString();
            
                                    console.log(preview.toString());
            
                                    previewImage.source = "image://provedorImagem/fotoPerfil"
                                }
                            }
                        }
            
                        VideoOutput {
                            id: viewfinder
                            
                            visible: true
            
                            focus: visible
            
                            anchors.top: parent.top
            
                            width: parent.width
                            height: parent.width
            
                            source: camera
                            
                            fillMode: VideoOutput.PreserveAspectCrop
                  }
            
            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 response for this code is:
            qml: image://camera/preview_1
            ""
            QFSFileEngine::open: No file name specified
            qrc:/CriarPerfil.qml:983:9: QML Image: Failed to get image from provider: image://provedorimagem/fotoPerfil

            p3c0P Offline
            p3c0P Offline
            p3c0
            Moderators
            wrote on last edited by
            #10

            @guidupas What does preview.toString() return ? Is it the actual image data or file name ?

            157

            1 Reply Last reply
            0
            • guidupasG Offline
              guidupasG Offline
              guidupas
              wrote on last edited by guidupas
              #11

              @p3c0 Hello!

              When I use console.log it returns the same result for both options:

              console.log(preview.toString());
              console.log(preview);
              

              The result is:
              qml: image://camera/preview_1

              But there is something wrong when I pass values to the Q_PROPERTY(QString imagem READ imagem WRITE setImagem NOTIFY imagemChanged). No matter what I pass it returns me an empty string.

              manipulaImagem.imagem = "AER";
              manipulaImagem.imagem = preview;
              manipulaImagem.imagem = preview.toString();
              

              All the options above returns the result:
              ""

              But I could not find what is missing.

              Att.
              Guilherme Cortada Dupas

              p3c0P 1 Reply Last reply
              0
              • guidupasG guidupas

                @p3c0 Hello!

                When I use console.log it returns the same result for both options:

                console.log(preview.toString());
                console.log(preview);
                

                The result is:
                qml: image://camera/preview_1

                But there is something wrong when I pass values to the Q_PROPERTY(QString imagem READ imagem WRITE setImagem NOTIFY imagemChanged). No matter what I pass it returns me an empty string.

                manipulaImagem.imagem = "AER";
                manipulaImagem.imagem = preview;
                manipulaImagem.imagem = preview.toString();
                

                All the options above returns the result:
                ""

                But I could not find what is missing.

                p3c0P Offline
                p3c0P Offline
                p3c0
                Moderators
                wrote on last edited by
                #12

                @guidupas That is the url with image id. You can now get the imageProvider from QML engine using that url. Cast QQmlImageProviderBase to QQuickImageProvider. Then you can use requestImage to get that actual camera image from image id. Once you get this image on C++ side perform operations and return it.

                157

                1 Reply Last reply
                0
                • guidupasG Offline
                  guidupasG Offline
                  guidupas
                  wrote on last edited by guidupas
                  #13

                  @p3c0 Hello!

                  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);

                  I think you told me to use something like the second way but I cannot return the image to QML.

                  Att.
                  Guilherme Cortada Dupas

                  p3c0P 1 Reply Last reply
                  0
                  • guidupasG guidupas

                    @p3c0 Hello!

                    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);

                    I think you told me to use something like the second way but I cannot return the image to QML.

                    p3c0P Offline
                    p3c0P Offline
                    p3c0
                    Moderators
                    wrote on last edited by
                    #14

                    @guidupas Returning a QImage wont work where QUrl is expected. Make this Image available for the image provider that your registered and then return this image from requestImage or requestPixmap.

                    157

                    1 Reply Last reply
                    0
                    • guidupasG Offline
                      guidupasG Offline
                      guidupas
                      wrote on last edited by
                      #15

                      @p3c0 Hello!

                      The problem is exactly 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.

                      Att.
                      Guilherme Cortada Dupas

                      p3c0P 1 Reply Last reply
                      0
                      • guidupasG guidupas

                        @p3c0 Hello!

                        The problem is exactly 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.

                        p3c0P Offline
                        p3c0P Offline
                        p3c0
                        Moderators
                        wrote on last edited by
                        #16

                        @guidupas But you already have the QImage (as per this error Error: Cannot assign QImage to QUrl in class manipulaImagem) as well as QQuickImageProvider instance. Is it not possible to send the image using this instance ?

                        157

                        1 Reply Last reply
                        0
                        • guidupasG Offline
                          guidupasG Offline
                          guidupas
                          wrote on last edited by
                          #17

                          @p3c0 I thing it can be possible but I am not figuring out how. Take a look at this code and I think you will understand what I am talking about.

                          .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
                                  }
                              }
                          

                          Now take a look at the output:

                          Loading image OK
                          Imagem is loaded
                          Request image: (image is null)
                          QML Image: Failed to get image from provider: image://provedorimagens/imagemEditada

                          How you can see 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.

                          Att.
                          Guilherme Cortada Dupas

                          p3c0P 1 Reply Last reply
                          0
                          • guidupasG guidupas

                            @p3c0 I thing it can be possible but I am not figuring out how. Take a look at this code and I think you will understand what I am talking about.

                            .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
                                    }
                                }
                            

                            Now take a look at the output:

                            Loading image OK
                            Imagem is loaded
                            Request image: (image is null)
                            QML Image: Failed to get image from provider: image://provedorimagens/imagemEditada

                            How you can see 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.

                            p3c0P Offline
                            p3c0P Offline
                            p3c0
                            Moderators
                            wrote on last edited by p3c0
                            #18

                            @guidupas Strange.. According to the order of the execution of the code, imagemEditada should not be null when the image is requested by Image element. May be I'm too missing something.

                            157

                            1 Reply Last reply
                            0
                            • guidupasG Offline
                              guidupasG Offline
                              guidupas
                              wrote on last edited by
                              #19

                              @p3c0 I found the error. I am targeting the wrong pointer. Actually I need to connect the provider pointer im main.cpp and I am creating a new pointer to the provider.

                              Att.
                              Guilherme Cortada Dupas

                              p3c0P 1 Reply Last reply
                              0
                              • guidupasG Offline
                                guidupasG Offline
                                guidupas
                                wrote on last edited by
                                #20

                                @p3c0 Could you take a look at this topic? I need some help to do exactly that connection between the provider pointer with a signal that send to it the QImage.
                                https://forum.qt.io/topic/60383/connecting-qquickimageprovider

                                Att.
                                Guilherme Cortada Dupas

                                1 Reply Last reply
                                0
                                • guidupasG guidupas

                                  @p3c0 I found the error. I am targeting the wrong pointer. Actually I need to connect the provider pointer im main.cpp and I am creating a new pointer to the provider.

                                  p3c0P Offline
                                  p3c0P Offline
                                  p3c0
                                  Moderators
                                  wrote on last edited by p3c0
                                  #21

                                  @guidupas said:

                                  @p3c0 I found the error. I am targeting the wrong pointer. Actually I need to connect the provider pointer im main.cpp and I am creating a new pointer to the provider.

                                  Well then pass the right pointer ?

                                  To use signals and slots you will need the right pointer too.

                                  157

                                  1 Reply Last reply
                                  0
                                  • guidupasG Offline
                                    guidupasG Offline
                                    guidupas
                                    wrote on last edited by guidupas
                                    #22

                                    @p3c0 I found the right pointer. It is in the main.cpp
                                    Now, how can I connect a slot inside this pointer to a signal in processaImagem.cpp?
                                    main.cpp

                                    #include <QGuiApplication>
                                    #include <QQmlApplicationEngine>
                                    
                                    #include <QtQml>
                                    
                                    #include "manipulaxml.h"
                                    #include "caminhoimagens.h"
                                    #include "manipulaimagem.h"
                                    
                                    int main(int argc, char *argv[])
                                    {
                                        QGuiApplication app(argc, argv);
                                    
                                        qmlRegisterType<manipulaXml>("ManipXML", 1, 0, "ManipulaXML");
                                        qmlRegisterType<caminhoImagens>("PathImagens", 1, 0, "CaminhoImagens");
                                        qmlRegisterType<manipulaImagem>("ManipImagem", 1, 0, "ManipulaImagem");
                                    
                                        QQmlApplicationEngine engine;
                                    
                                        manipulaImagem *imageProvider = new manipulaImagem;
                                        engine.addImageProvider("ProvedorImagens", imageProvider);
                                    
                                        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                    
                                        return app.exec();
                                    }
                                    

                                    Att.
                                    Guilherme Cortada Dupas

                                    p3c0P 1 Reply Last reply
                                    0
                                    • guidupasG guidupas

                                      @p3c0 I found the right pointer. It is in the main.cpp
                                      Now, how can I connect a slot inside this pointer to a signal in processaImagem.cpp?
                                      main.cpp

                                      #include <QGuiApplication>
                                      #include <QQmlApplicationEngine>
                                      
                                      #include <QtQml>
                                      
                                      #include "manipulaxml.h"
                                      #include "caminhoimagens.h"
                                      #include "manipulaimagem.h"
                                      
                                      int main(int argc, char *argv[])
                                      {
                                          QGuiApplication app(argc, argv);
                                      
                                          qmlRegisterType<manipulaXml>("ManipXML", 1, 0, "ManipulaXML");
                                          qmlRegisterType<caminhoImagens>("PathImagens", 1, 0, "CaminhoImagens");
                                          qmlRegisterType<manipulaImagem>("ManipImagem", 1, 0, "ManipulaImagem");
                                      
                                          QQmlApplicationEngine engine;
                                      
                                          manipulaImagem *imageProvider = new manipulaImagem;
                                          engine.addImageProvider("ProvedorImagens", imageProvider);
                                      
                                          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                      
                                          return app.exec();
                                      }
                                      
                                      p3c0P Offline
                                      p3c0P Offline
                                      p3c0
                                      Moderators
                                      wrote on last edited by
                                      #23

                                      @guidupas Don't register the manipulaImagem class. Instead set it as a context property too as you already have that instance.
                                      manipulaImagem *imageProvider = new manipulaImagem
                                      In this way you access the same instance from QML for both Image and as context property.

                                      157

                                      1 Reply Last reply
                                      0
                                      • guidupasG Offline
                                        guidupasG Offline
                                        guidupas
                                        wrote on last edited by
                                        #24

                                        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;
                                        }
                                        

                                        Att.
                                        Guilherme Cortada Dupas

                                        p3c0P 1 Reply Last reply
                                        0
                                        • guidupasG guidupas

                                          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;
                                          }
                                          
                                          p3c0P Offline
                                          p3c0P Offline
                                          p3c0
                                          Moderators
                                          wrote on last edited by
                                          #25

                                          @guidupas That is what I said in earlier post :). Please make the post as solved if done.

                                          157

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved