web-dev-qa-db-de.com

So übergeben Sie die Bildvorschau von der QML-Kamerakomponente an ein C ++ - Plugin

Ich schreibe eine Ubuntu Touch QML-App, die Bilder von einem Kameragerät aufzeichnet und verarbeitet. Die Verarbeitung erfolgt über ein C++ - Plugin, an das ich die URL des Bildes übergebe.

Ich kann Bilder erfolgreich speichern und vom C++ - Plugin laden, aber ich muss die Bilder lieber nicht zuerst im Dateisystem speichern und stattdessen die speicherinterne Kameravorschau an das Plugin übergeben.

Angesichts der URL für die Vorschau, die ich von der Kamera erhalte (image://camera/preview_1), schätze ich, dass ich in der Lage sein sollte, einen Verweis auf den "camera"Bildanbieter zu erhalten Verwenden Sie anschließend die requestImage () -Methode, um das Bild abzurufen.

Ich konnte jedoch nicht herausfinden, wie ich an den Image-Provider camera komme. Hier ist der Code:

QString Decoder::decodeImageQML(const QUrl &imgUrl)
{
    /* 
     * @imgUrl: URL to the camera preview. E.g. image://camera/preview_1
     */

    QQmlEngine * engine;
    QQuickImageProvider *imageProvider = 0;

    // FIXME: this does not work, I'm not sure how to get hold of 
    // the image provider
    imageProvider = engine->imageProvider("camera");

    QImage image = imageProvider->requestImage(("preview_1", &size, QSize());

    return Decoder::decodeImage(image);
}

Wie erhalte ich einen Verweis auf den Image-Anbieter camera?

7
David Planella

Sie können eine gültige Engine-Instanz mithilfe der folgenden Syntax abrufen.

QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();

Und um den Zeiger des Bildanbieters zu erhalten, können Sie Folgendes tun:

QQmlImageProviderBase* imageProviderBase = engine->imageProvider(item.Host());
QQuickImageProvider* imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);

Da QQuickImageProvider von QQmlImageProviderBase abgeleitet ist, halte ich diese Besetzung für in Ordnung. Ich bin nicht sicher, wie wir sonst den Zeiger von QQuickImageProvider von der Engine erhalten können.

4
Kunal

Um das Vorschaubild in C++ zu erhalten, müssen Sie die Eigenschaft mediaObject des Elements QML Camera an C++ übergeben. Sie können diesen Code in der Kamera-App als Beispiel sehen.

Sie könnten versuchen, das QCameraImageCapture mit diesem mediaObject zu verwenden. Aber ich bin mir nicht sicher, ob das funktionieren wird. Aber es hat das imageCaptured-Signal, das Sie benötigen. Das hat ein QImage mit der Vorschau.

void AdvancedCamera::setCamera(QObject *cameraObject)
{
    QVariant cameraVariant = cameraObject->property("mediaObject");
    QCamera *camera = qvariant_cast<QCamera*>(cameraVariant);
    QCameraImageCapture *imageCapture = new QCameraImageCapture(camera);
    QObject::connect(imageCapture, SIGNAL(imageCaptured(int, const QImage&))
        myObject, SLOT(processPreview(int, const QImage&)));
}

Wenn dies nicht funktioniert, können Sie auf folgende Weise QCameraImageCaptureControl des QMediaService verwenden:

void AdvancedCamera::setCamera(QObject *cameraObject)
{
    QVariant cameraVariant = cameraObject->property("mediaObject");
    QCamera *camera = qvariant_cast<QCamera*>(cameraVariant);
    QMediaService *service = camera->service();
    QMediaControl *control = service->requestControl(QCameraImageCaptureControl_iid);
    QCameraImageCaptureControl *captureControl = qobject_cast<QCameraImageCaptureControl*>(control);
    QObject::connect(captureControl, SIGNAL(imageCaptured(int, const QImage&))
        myObject, SLOT(processPreview(int, const QImage&)));
}

Sie sollten sich den Code der Kamera-App ansehen, um ein besseres Beispiel zu erhalten.

Damit das endgültige Bild in C++ als QVideoFrame geliefert wird, müssen Sie captureDestination festlegen. Dies wird vom Kamera-Backend der Ubuntu-Telefone (noch?) Nicht unterstützt.

3
Günter Schwann