Я создаю приложение с кроссплатформенностью Qt
и в этом приложении мне нужно отобразить результат одного QCamera
на двух разных экранах. Это включает в себя ссылку на два QCameraViewFinder
на том же QCamera
,
Мой код:
QCameraViewFinder* viewfinder = new QCameraViewFinder();
QCamera* camera = new QCamera();
viewfinder->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
camera->setViewfinder(ui->viewfinder);
QCamera::CaptureModes captureMode = QCamera::CaptureStillImage ;
camera->setCaptureMode(captureMode);
Проблема в том, что я не могу использовать другой QCameraViewFinder для отслеживания моей QCamera. И мне нужно сделать это, потому что я хотел бы отобразить два QCameraViewFinder на двух разных экранах.
Я действительно застрял в этой теме, так что, если у некоторых людей есть решение, это было бы здорово!
На самом деле вы можете создать два разных экземпляра QCamera и установить для них два разных видоискателя, но вы не сможете запустить камеру дважды (т. Е. У вас получится какой-то вид занятое устройство ошибка).
Если все, что вам нужно, это простая реализация видоискателя, вы можете создать подкласс QAbstractVideoSurface
и пересылать видеокадры через сигналы следующим образом:
sharedviewfinder.h
#include <QAbstractVideoSurface>
#include <QPixmap>
class SharedViewfinder : public QAbstractVideoSurface
{
Q_OBJECT
public:
SharedViewfinder();
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const;
bool present(const QVideoFrame &frame);
signals:
void frameReady(QPixmap);
};
sharedviewfinder.cpp
#include "sharedviewfinder.h"
SharedViewfinder::SharedViewfinder() : QAbstractVideoSurface(nullptr){}
QList<QVideoFrame::PixelFormat> SharedViewfinder::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
QList<QVideoFrame::PixelFormat> list;
if (handleType == QAbstractVideoBuffer::NoHandle)
{
list.append(QVideoFrame::Format_RGB32);
}
return list;
}
bool SharedViewfinder::present(const QVideoFrame &frame)
{
QVideoFrame copy(frame);
copy.map(QAbstractVideoBuffer::ReadOnly);
QImage image(copy.bits(), copy.width(), copy.height(), copy.bytesPerLine(), QImage::Format_RGB32);
copy.unmap();
emit frameReady(QPixmap::fromImage(image));
return true;
}
Чтобы показать перенаправленные кадры, в виджете по вашему выбору, есть QLabel
и слот, как это:
void Widget::frameReady(QPixmap pixmap)
{
label->setPixmap(pixmap);
label->update();
}
Теперь вы можете установить общий видоискатель на объект камеры и связать его с несколькими видами:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SharedViewfinder viewfinder;
Widget mirror1;
Widget mirror2;
QObject::connect(&viewfinder, &SharedViewfinder::frameReady, &mirror1, &Widget::frameReady);
QObject::connect(&viewfinder, &SharedViewfinder::frameReady, &mirror2, &Widget::frameReady);
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
QCamera camera(cameras[0]);
camera.setViewfinder(&viewfinder);
mirror1.move(0, 0);
mirror1.show();
mirror2.move(1920, 0);
mirror2.show();
camera.start();
return a.exec();
}
Я надеюсь, что это работает из коробки, в любом случае вы можете изменить цветовой формат, который я установил на RGB32. Также обратите внимание, что я перемещаю представления, чтобы показать их на обоих экранах, которые у меня есть. Пример кода, который я предоставляю, был успешно протестирован (но очень поверхностно) на ноутбуке Ubuntu 16.10 Asus.
Других решений пока нет …