Я пишу Касанию Ubuntu приложение QML, которое получает и обрабатывает изображения от устройства камеры. Обработка сделана плагином C++, которому я передаю URL изображения.
Я могу успешно сохранить образы и загрузить их из плагина C++, но я не должен сохранить образы в файловой системе сначала и передать предварительный просмотр камеры в оперативной памяти плагину вместо этого.
Учитывая URL для предварительного просмотра, который я получаю от камеры (image://camera/preview_1
), я предполагаю, что должен смочь получить ссылку на "camera"
отобразите поставщика и затем используйте requestImage () метод для получения изображения.
Однако я не смог выяснить, как овладеть camera
поставщик изображения. Вот код:
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);
}
Как я получаю ссылку на camera
поставщик изображения?
Вы можете получить действительный экземпляр движка, используя следующий синтаксис.
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
И чтобы получить указатель поставщика изображения, вы можете сделать что-то вроде следующего:
QQmlImageProviderBase* imageProviderBase = engine->imageProvider(item.host());
QQuickImageProvider* imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);
Поскольку QQuickImageProvider является производным от QQmlImageProviderBase, я думаю, что это приведение в порядке. Не уверен, как иначе мы можем получить указатель на QQuickImageProvider из движка.
Чтобы получить изображение предварительного просмотра в C ++, вы должны передать свойство mediaObject элемента QML Camera в C ++. Вы можете увидеть этот код в приложении камеры в качестве примера.
Вы можете попробовать использовать QCameraImageCapture с этим mediaObject
. Но я не уверен, что это сработает. Но у него есть сигнал imageCaptured, который вам понадобится. Это имеет QImage с предварительным просмотром.
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&)));
}
Если это не работает, вот еще один способ, используя QCameraImageCaptureControl из 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&)));
}
Вы должны посмотреть код приложения для камеры для лучшего примера.
Чтобы получить окончательное изображение, доставленное как QVideoFrame в C ++, вам нужно установить captureDestination. Но это (пока?) Не поддерживается бэкэндом камеры телефонов Ubuntu.