我目前正在使用QML制作跨平台应用(Android,iOS),我需要进行QR码扫描功能。 QR码读数正在使用ZXing,没有问题,问题在于相机。 我无法从QCamera中提取视频帧。
有一个模块QVideoProbe
应该为我做。但是,它不起作用
,而不是在Win32上,而不是在OSX上。它根本不适用于桌面平台。我没有在这台电脑上使用我的代码,但它就像我在论坛上找到的这个例子一样
QCamera *camera = new QCamera;
camera->setCaptureMode(QCamera::CaptureVideo);
QCameraViewfinder *viewfinder = new QCameraViewfinder();
camera->setViewfinder(viewfinder);
qDebug() << " start set source";
QVideoProbe *videoProbe = new QVideoProbe(this);
if (videoProbe->setSource((QMediaObject *)camera)) {
qDebug() << " set source succeed";
//Probing succeeded, videoProbe->isValid() should be true.
connect(videoProbe, SIGNAL(videoFrameProbed(const QVideoFrame &)),this,SLOT(detectAVA(const QVideoFrame &)));
}
camera->start();
论坛上的人跟我有同样的问题。这一行:
videoProbe->setSource((QMediaObject *)camera)
将返回false
。
论坛上的回复是:
使用(传递)
Camera
元素作为sourceObj,会发生什么?它也可以。
那是理论上的。在实践中,它取决于平台。
QVideoProbe
并非全部可用(或仅适用于a 媒体播放器或相机)。它应该在文档中,但这里是对
QVideoProbe
的概述 支持:
- Android:仅适用于相机
- 黑莓:不支持
- iOS:不支持
- Linux:仅适用于媒体播放器
- Mac:不支持
- Windows:仅适用于媒体播放器
如果它不受支持,它并不一定意味着它不可能 在给定的平台上进行,它可能意味着它目前不是 实现。
所以,Android只是支持Camera的平台,那么我就是 在Win32上寻找支持,我愿意在win32下添加支持, 这项工作真的很难,我会把它合并到Qt中 主线。
此外,我将在Android下添加媒体播放器支持。那是两个 功能我正在寻找。
看起来它没有实现,如果这样可行,它只适用于Android,我必须在真实手机上进行测试(模拟器无法正常工作)。
我想从相机中提取帧是任何平台和语言的基本功能。一定有办法。有没有解决方案?
答案 0 :(得分:0)
我使用hack实现了这一点。它有点像预期的那样工作。我们的想法是使用QAbstractVideoSurface
作为QVideoProbe
的临时替代方案。它有许多缺点,但至少它是一些东西。
下面的代码编译但我老实说不知道它是否有效(它已经暂停了一段时间)。使用风险自负!
<强> PoorMansProbe.hpp 强>
#ifndef POORMANSPROBE_HPP
#define POORMANSPROBE_HPP
#include <QAbstractVideoSurface>
#include <QList>
class QCamera;
class QCameraViewfinder;
class PoorMansProbe : public QAbstractVideoSurface
{
Q_OBJECT
private:
QCamera *source;
public:
explicit PoorMansProbe(QObject *parent = nullptr);
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const;
// Called from QAbstractVideoSurface whenever a new frame is present
bool present(const QVideoFrame &frame) Q_DECL_OVERRIDE;
bool setSource(QCamera *source);
bool isActive() const;
signals:
// Users of this class will get frames via this signal
void videoFrameProbed(const QVideoFrame &videoFrame);
void flush();
};
#endif // POORMANSPROBE_HPP
<强> PoorMansProbe.cpp 强>
#include "PoorMansProbe.hpp"
#include <QVideoFrame>
#include <QCamera>
#include <QCameraViewfinder>
PoorMansProbe::PoorMansProbe(QObject *parent)
: QAbstractVideoSurface(parent)
, source(0)
{
}
QList<QVideoFrame::PixelFormat> PoorMansProbe::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
Q_UNUSED(handleType);
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_RGB24
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_RGB555
<< QVideoFrame::Format_ARGB8565_Premultiplied
<< QVideoFrame::Format_BGRA32
<< QVideoFrame::Format_BGRA32_Premultiplied
<< QVideoFrame::Format_BGR32
<< QVideoFrame::Format_BGR24
<< QVideoFrame::Format_BGR565
<< QVideoFrame::Format_BGR555
<< QVideoFrame::Format_BGRA5658_Premultiplied
<< QVideoFrame::Format_AYUV444
<< QVideoFrame::Format_AYUV444_Premultiplied
<< QVideoFrame::Format_YUV444
<< QVideoFrame::Format_YUV420P
<< QVideoFrame::Format_YV12
<< QVideoFrame::Format_UYVY
<< QVideoFrame::Format_YUYV
<< QVideoFrame::Format_NV12
<< QVideoFrame::Format_NV21
<< QVideoFrame::Format_IMC1
<< QVideoFrame::Format_IMC2
<< QVideoFrame::Format_IMC3
<< QVideoFrame::Format_IMC4
<< QVideoFrame::Format_Y8
<< QVideoFrame::Format_Y16
<< QVideoFrame::Format_Jpeg
<< QVideoFrame::Format_CameraRaw
<< QVideoFrame::Format_AdobeDng;
}
bool PoorMansProbe::present(const QVideoFrame &frame)
{
if (frame.isValid()) {
emit videoFrameProbed(frame);
return true;
}
return false;
}
bool PoorMansProbe::setSource(QCamera *source)
{
this->source=source;
source->setViewfinder(this);
QCameraViewfinderSettings viewfinderSettings;
// I have a broken camera that only support these settings, but you should put whatever settings you need here
viewfinderSettings.setResolution(640, 480);
viewfinderSettings.setMinimumFrameRate(0.0);
viewfinderSettings.setMaximumFrameRate(30.0);
source->setViewfinderSettings(viewfinderSettings);
return true;
}
bool PoorMansProbe::isActive() const
{
return (0!=source);
}