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

7

Ich schreibe eine Ubuntu Touch QML-App, die Bilder von einem Kameragerät erfasst 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 Vorschau der In-Memory-Kamera an das Plugin übergeben.

Die URL für die Vorschau Da ich von der Kamera (bin immer image://camera/preview_1), ich vermute , ich soll in der Lage einen Verweis auf das bekommen "camera" Bildanbieter und dann die Verwendung requestImage () Methode um das Bild zu bekommen.

Ich konnte jedoch nicht herausfinden, wie ich an den cameraBildanbieter gelangen kann. 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 cameraBildanbieter?

David Planella
quelle
1
Ich hatte in einer meiner Apps etwas Ähnliches getan, aber ich entschied mich für einen entgegengesetzten Ansatz. Ich habe ein Vorschaubild mit dem View Finder und der Verarbeitung im C ++ - Plugin erhalten und es dann mit einem benutzerdefinierten Bildanbieter für die QML-App freigegeben.
Kunal

Antworten:

4

Sie können eine gültige Engine-Instanz mit 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, denke ich, dass diese Besetzung in Ordnung ist. Ich bin mir nicht sicher, wie wir sonst den Zeiger von QQuickImageProvider von der Engine erhalten können.

Kunal
quelle
1
Ich denke, Sie sollten einen dynamic_cast anstelle eines static_cast verwenden und möglicherweise das Ergebnis überprüfen, siehe z. B. stackoverflow.com/questions/28002/…
ssc
3

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

Sie könnten versuchen, QCameraImageCapture damit zu verwenden mediaObject. 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 es nicht funktioniert, können Sie das QCameraImageCaptureControl des QMediaService auf folgende Weise 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&)));
}

Ein besseres Beispiel finden Sie im Code der Kamera-App .

Um das endgültige Image als QVideoFrame in C ++ zu erhalten, müssen Sie die CaptureDestination festlegen. Aber das wird (noch?) Vom Kamera-Backend der Ubuntu-Handys nicht unterstützt.

Günter Schwann
quelle