gpt4 book ai didi

android - 捕获图像而不保存

转载 作者:行者123 更新时间:2023-11-28 05:36:27 24 4
gpt4 key购买 nike

基于此thread , 有没有办法在不保存的情况下在 QML 中处理来自相机的图像?

doc的例子开始capture() 函数将图像保存到图片位置。我想要实现的是使用 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"));

一旦你获得了摄像头的钩子(Hook),就可以将其用作 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();
}

这里有两个重要的实现细节:

  1. Android 设备使用 YUV format QImage 目前不支持,应该手动转换。我在这里做了一个强有力的假设,即所有无效格式都是 YUV。在当前操作系统上通过 ifdef 的条件可以更好地管理。
  2. 解码的成本可能很高,因此您可以跳过帧(只需为此方法添加一个计数器)或将工作卸载到专用线程。这也取决于制定框架的速度。同时减小它们的尺寸,例如只取 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 代码和处理代码之间更好的耦合。这是以(稍微)更高的实现工作为代价的。

关于android - 捕获图像而不保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38203681/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com