Есть два QCameraViewFinder для одного QCamera

Я создаю приложение с кроссплатформенностью 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 на двух разных экранах.

Я действительно застрял в этой теме, так что, если у некоторых людей есть решение, это было бы здорово!

1 ответ

Решение

На самом деле вы можете создать два разных экземпляра 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.

Другие вопросы по тегам