基于此thread,有没有办法在QML中处理来自相机的图像而不保存它?在不保存的情况下捕获图像
从doc的示例开始,capture()函数将图像保存到Pictures位置。 我想实现的目标是每秒钟使用onImageCaptured处理相机图像,但我不想将其保存到驱动器。
我试过使用onImageSaved信号来实现清理操作,但它也影响onImageCaptured。
基于此thread,有没有办法在QML中处理来自相机的图像而不保存它?在不保存的情况下捕获图像
从doc的示例开始,capture()函数将图像保存到Pictures位置。 我想实现的目标是每秒钟使用onImageCaptured处理相机图像,但我不想将其保存到驱动器。
我试过使用onImageSaved信号来实现清理操作,但它也影响onImageCaptured。
如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 format。我在这里做出了强有力的假设,即所有无效的格式都是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
代码和处理代码之间的更好的耦合。这是以牺牲(稍微)更高的实施努力为代价的。
这真的取决于你想要的。如果您只想处理帧(例如搜索标记/ Qr代码),则可以将[mediaObject](http://doc.qt.io/qt-5/qml-qtmultimedia-camera.html#mediaObject-prop )就是这样。如果你想做实时过滤和覆盖,那么需要做更多的工作。有关第二种场景的更多详细信息,请参阅[本答案](http://stackoverflow.com/a/33238150/2538363)开头处的链接。 – BaCaRoZzo
我想实现的是扫描QR码。由于我不能使用grabWindow(),因为[this](https://bugreports.qt.io/browse/QTBUG-53083),我想每秒捕获一次摄像头输出并处理图像。 – ABCplus
因此,根据您使用mediaObject的建议,一旦我获得对QCamera对象的引用,那么我需要做什么? – ABCplus