任务是从 QVideoFrame 复制一个帧,并可能对该图像执行某些操作并以QML显示操作的图像。
...
m_lastFrame = QImage(videoFrame.width(), videoFrame.height(), QImage::Format_ARGB32);
memcpy(m_lastFrame.bits(), videoFrame.bits(),videoFrame.mappedBytes());
...
以上代码导致崩溃,因为m_lastFrame缺少32个字节(3686400 vs 3686432) videoFrame.mappedBytes()报告3686432个字节。我在这做错了什么?或者我应该如何计算m_lastFrame()的大小。
代码在Mac OSx 10.9.5 Qt 5.1.1上运行。
一些额外的代码:
... if(videoFrame。 map(QAbstractVideoBuffer :: ReadOnly)){
m_lastFrame = QImage(videoFrame.width(),videoFrame.height(),QImage::Format_ARGB32);
memcpy(m_lastFrame.bits(), videoFrame.bits(),videoFrame.mappedBytes() - 32);
...
} ...
答案 0 :(得分:1)
由于这并不总是有效,请参见convert QVideoFrame to QImage的评论,即
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;
}
答案 1 :(得分:0)
您可以尝试通过以下方式将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;
}
如果你想要任何其他格式的QImage,只需在创建图像时将最后一个参数更改为你喜欢的任何格式:
QImage :: Format_xxx;
而不是
QVideoFrame :: imageFormatFromPixelFormat(cloneFrame .pixelFormat()));