如何QVideoFrame到QImage

时间:2014-12-04 15:24:16

标签: qt

任务是从 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);

    ...

} ...

2 个答案:

答案 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()));