2014-12-04 2 views
0

Задача состоит в том, чтобы скопировать кадр с QVideoFrame и, возможно, сделать что-то с этим изображением и отобразить управляемое изображение в QML.Как QVideoFrame для QImage

...

m_lastFrame = QImage(videoFrame.width(), videoFrame.height(), QImage::Format_ARGB32); 
memcpy(m_lastFrame.bits(), videoFrame.bits(),videoFrame.mappedBytes()); 

...

Приведенный выше код вызывает сбой, поскольку m_lastFrame не хватает 32 байт (3686400 против 3686432) videoFrame.mappedBytes() сообщает 3686432 байт. Что я здесь делаю неправильно? Или как мне рассчитать размер m_lastFrame().

Код работает на Mac OSx 10.9.5 Qt 5.1.1.

Некоторый дополнительный код:

... если (VideoFrame карта (QAbstractVideoBuffer :: ReadOnly).) {

m_lastFrame = QImage(videoFrame.width(),videoFrame.height(),QImage::Format_ARGB32); 
    memcpy(m_lastFrame.bits(), videoFrame.bits(),videoFrame.mappedBytes() - 32); 

    ... 

} ...

+0

Вы называли 'videoFrame.map (QAbstractVideoBuffer :: ReadOnly)' и проверил возвращаемое значение? Вы уверены, что видеокадр содержит данные ARGB32? – njahnke

+0

Вы успешно сопоставляете (с вызовом 'map()') содержимое видеокадра в системную память перед вызовом 'videoFrame.bits()'? В этом случае я думаю, что ваша проблема должна быть решена путем правильного преобразования из формата пикселя в формат изображения. – mhcuervo

+0

Да @njahnke. Я нахожу карту() в соответствии с вышеизложенным

ответ

0

Вы можете попробовать создавая QImage, сначала сопоставив QVideoFrame с QAbstractVideoBuffer следующим образом:

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

+0

Вы не можете просто указать формат, который вам нравится. Он должен быть форматом данных, которые вы предоставляете, поэтому требуется QVideoFrame :: imageFormatFromPixelFormat'. –

0

Так что не всегда работает, смотрите также комментарий на 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; 
} 
Смежные вопросы