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. QML Camera running in Android dies
Qt 6.11 is out! See what's new in the release blog

QML Camera running in Android dies

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qmlcameraqt programmingandroid
1 Posts 1 Posters 1.3k Views 1 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 Offline
    guidupasG Offline
    guidupas
    wrote on last edited by guidupas
    #1

    I am developing an app that uses a QML Camera element. The problem is that after taking some photos the camera dies and does not work anymore until I reopen the app. Could anyone help me?

    I tried to use camera.cameraState = Camera.LoadedState before the camera.start() and camera.cameraState = Camera.UnloadedState after the camera.stop(), but it killed my entire app, not just the camera.

    Ps: I have tested it just in Android until now. I am going to see if it happens in iOS too.

    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

    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