根据这个thread,有没有办法在不保存的情况下用QML处理相机中的图像?
从doc capture()函数的示例开始,将图像保存到图片位置。 我想要实现的是使用onImageCaptured每秒处理相机图像,但我不想将其保存到驱动器。
我尝试使用onImageSaved信号实现清理操作,但它也会影响onImageCaptured。
答案 0 :(得分:1)
如this answer中所述,您可以通过mediaObject
桥接C ++和QML。这可以通过objectName
完成(如在链接的答案中)或使用专用的Q_PROPERTY
(稍后会详细介绍)。无论哪种情况,你都应该得到这样的代码:
QObject * source // QML camera pointer obtained as described above
QObject * cameraRef = qvariant_cast<QMediaObject*>(source->property("mediaObject"));
一旦你拿到相机的钩子,就把它用作QVideoProbe
物体的来源,即
QVideoProbe *probe = new QVideoProbe;
probe->setSource(cameraRef);
将videoFrameProbed
信号连接到适当的插槽,即
connect(probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
就是这样:您现在可以在processFrame
函数内处理您的帧。这样一个函数的实现如下所示:
void YourClass::processFrame(QVideoFrame frame)
{
QVideoFrame cFrame(frame);
cFrame.map(QAbstractVideoBuffer::ReadOnly);
int w {cFrame.width()};
int h {cFrame.height()};
QImage::Format f;
if((f = QVideoFrame::imageFormatFromPixelFormat(cFrame.pixelFormat())) == QImage::Format_Invalid)
{
QImage image(cFrame.size(), QImage::Format_ARGB32);
// NV21toARGB32 convertion!!
//
// DECODING HAPPENS HERE on "image"
}
else
{
QImage image(cFrame.bits(), w, h, f);
//
// DECODING HAPPENS HERE on "image"
}
cFrame.unmap();
}
这里有两个重要的实施细节:
QImage
不支持,应该手动转换。我在这里强烈假设所有无效格式都是YUV。通过当前操作系统上的ifdef
条件,可以更好地管理。QImage
的一部分可以大大提高表现。就此而言,我会完全避免objectName
获取mediaObject
的方法,而是register a new type,以便可以使用Q_PROPERTY
方法。我正在考虑这个问题:
class FrameAnalyzer
{
Q_OBJECT
Q_PROPERTY(QObject* source READ source WRITE setSource)
QObject *m_source; // added for the sake of READ function
QVideoProbe probe;
// ...
public slots:
void processFrame(QVideoFrame frame);
}
setSource
只是:
bool FrameAnalyzer::setSource(QObject *source)
{
m_source = source;
return probe.setSource(qvariant_cast<QMediaObject*>(source->property("mediaObject")));
}
像往常一样注册,即
qmlRegisterType<FrameAnalyzer>("FrameAnalyzer", 1, 0, "FrameAnalyzer");
您可以直接在QML中设置source
属性,如下所示:
// other imports
import FrameAnalyzer 1.0
Item {
Camera {
id: camera
// camera stuff here
Component.onCompleted: analyzer.source = camera
}
FrameAnalyzer {
id: analyzer
}
}
这种方法的一大优点是可读性和Camera
代码与处理代码之间更好的耦合。这是以(稍微)更高的实施工作为代价的。