Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I'm writing an Ubuntu Touch QML app that captures and processes images from a camera device. The processing is done by a C++ plugin to which I'm passing the URL of the image.

I can successfully save images and load them from the C++ plugin, but I'd rather not have to save the images on the filesystem first, and pass the in-memory camera preview to the plugin instead.

Given the URL for the preview that I'm getting from the camera (image://camera/preview_1), I'm guessing I should be able to get a reference to the "camera" image provider and then use the requestImage() method to get the image.

However, I've not been able to figure out how to get hold of the camera image provider. Here's the 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);
}

How do I get a reference to the camera image provider?

share|improve this question
1  
I had done similar thing in one of my app, but I chosen opposite approach. I was getting preview image using View Finder and processing in c++ plugin and then sharing them to QML app using custom Image provider. –  Kunal Jun 3 '13 at 1:28

2 Answers 2

up vote 3 down vote accepted

You can get valid engine instance using following syntax.

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

And to get pointer of image provider, you can do something like following,

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

As QQuickImageProvider is derived from QQmlImageProviderBase, I think this cast is ok. Not sure how otherwise we can get pointer of QQuickImageProvider from engine.

share|improve this answer
1  
I think you should use a dynamic_cast instead of a static_cast and possibly check the result, see e.g. stackoverflow.com/questions/28002/… –  ssc Jun 4 '13 at 21:35

To get the preview image in C++, you should pass the mediaObject property of the QML Camera element to C++. You can see that code in the camera-app as example.

You could try to use the QCameraImageCapture with that mediaObject. But I'm not sure if that will work. But it has the imageCaptured signal you'll need. That has a QImage with the preview.

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

If it doesn't work, here is another way, using the QCameraImageCaptureControl of the QMediaService:

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

You should look a the code of the camera-app for a better example.

For getting the final image delivered as QVideoFrame in C++, you would need to set the captureDestination. But that's not (yet?) supported by the camera backend of the Ubuntu phones.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.