Qt 如何将QVideoFrame转换为QImage
任务是从QVideoFrame复制一个帧,并可能对该图像执行某些操作,并在QML中显示处理后的图像 上面的代码会导致崩溃,因为m_lastFrame缺少32个字节(3686400对3686432) videoFrame.mappedBytes()报告3686432字节。我做错了什么?或者我应该如何计算m_lastFrame()的大小 该代码在Mac OSx 10.9.5 Qt 5.1.1上运行 一些附加代码: 。。。 if(videoFrame.映射(QAbstractVideoBuffer::ReadOnly)){ }Qt 如何将QVideoFrame转换为QImage,qt,Qt,任务是从QVideoFrame复制一个帧,并可能对该图像执行某些操作,并在QML中显示处理后的图像 上面的代码会导致崩溃,因为m_lastFrame缺少32个字节(3686400对3686432) videoFrame.mappedBytes()报告3686432字节。我做错了什么?或者我应该如何计算m_lastFrame()的大小 该代码在Mac OSx 10.9.5 Qt 5.1.1上运行 一些附加代码: 。。。 if(videoFrame.映射(QAbstractVideoBuffer
…您可以尝试通过以下方式首先将QVideoFrame映射到QAbstractVideoBuffer来创建QImage:
bool CameraFrameGrabber::present(const QVideoFrame &frame)
{
Q_UNUSED(frame);
if (frame.isValid()) {
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat()));
emit frameAvailable(image);
qDebug()<<cloneFrame.mappedBytes();
cloneFrame.unmap();
return true;
}
bool-CameraFrameGrabber::present(const-QVideoFrame&frame)
{
Q_未使用(帧);
if(frame.isValid()){
QVideoFrame克隆帧(frame);
map(QAbstractVideoBuffer::ReadOnly);
常量图像(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat());
发射帧可用(图像);
qDebug()由于这并不总是有效,请参见的注释,即
您是否调用了videoFrame.map(QAbstractVideoBuffer::ReadOnly)
并检查了返回值?您是否确定视频帧包含ARGB32数据?在调用videoFrame.bits()之前,您是否成功地(通过调用map()
)将视频帧的内容映射到系统内存
?在这种情况下,我认为应该通过将像素格式正确转换为图像格式来解决您的问题。是@njahnke。我正在调用map()根据上面的
好的,@mhcuervo。谢谢你们的宝贵意见。我检查了格式,它使用的格式正确。我将在pc上运行此代码,看看结果如何。在Windows 8上使用Qt 5.3.2进行了测试。两个函数都返回了3686400字节。因此,MAC上似乎存在问题。但是,发现了其他问题在PC上,返回的帧是颠倒的,RGB32图像只渲染了一个白色帧。转换为ARGB_32并渲染图像。下一步将使用一些日志来调查实际像素值。想法是在多个平台上使用它,到目前为止,Qt fw似乎无法提供良好的跨平台功能。您无法指定您喜欢的格式。它必须是您提供的数据的格式,因此需要QVideoFrame::imageFormatFromPixelFormat
。
m_lastFrame = QImage(videoFrame.width(),videoFrame.height(),QImage::Format_ARGB32);
memcpy(m_lastFrame.bits(), videoFrame.bits(),videoFrame.mappedBytes() - 32);
...
bool CameraFrameGrabber::present(const QVideoFrame &frame)
{
Q_UNUSED(frame);
if (frame.isValid()) {
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat()));
emit frameAvailable(image);
qDebug()<<cloneFrame.mappedBytes();
cloneFrame.unmap();
return true;
}
QImage Camera::imageFromVideoFrame(const QVideoFrame& buffer) const
{
QImage img;
QVideoFrame frame(buffer); // make a copy we can call map (non-const) on
frame.map(QAbstractVideoBuffer::ReadOnly);
QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(
frame.pixelFormat());
// BUT the frame.pixelFormat() is QVideoFrame::Format_Jpeg, and this is
// mapped to QImage::Format_Invalid by
// QVideoFrame::imageFormatFromPixelFormat
if (imageFormat != QImage::Format_Invalid) {
img = QImage(frame.bits(),
frame.width(),
frame.height(),
// frame.bytesPerLine(),
imageFormat);
} else {
// e.g. JPEG
int nbytes = frame.mappedBytes();
img = QImage::fromData(frame.bits(), nbytes);
}
frame.unmap();
return img;
}