提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
在qt框架下,实现相机预览的几种方式在qt相机预览已经描述过了,在该文章的几种方式中,往往需要用到本文的内容,即QVideoFrame与QImage的转换,本文描述下笔者用到的几种方法
该方法有点不依赖其他的c++库
static QImage imageFromVideoFrame(const QVideoFrame& buffer)
{
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;
}
当方法一的方法行不通时,比如某些特殊的图片格式,QImage不支持的情况下可借鉴
依赖opencv库做一些图像格式转换
#include
void QImage imageFromVideoFrame(const QVideoFrame &frame)
{
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
int width = cloneFrame.width();
int height = cloneFrame.height();
QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat());
cv::Mat yuvimg(height * 3 / 2, width, CV_8UC1, (unsigned char *)cloneFrame.bits());
cv::Mat rgbimg(height, width, CV_8UC3);
cv::cvtColor(yuvimg, rgbimg, cv::COLOR_YUV2RGB_NV21);
QImage image( rgbimg.data, rgbimg.cols, rgbimg.rows, rgbimg.step, QImage::Format_RGB888 );
cloneFrame.unmap();
return image;
}
const QVideoFrame &frame;
QImage image = frame.image(); // This function was introduced in Qt 5.15.
QImage::Format ifmt = image.format();
qDebug() << ifmt;
emit frameAvailable(image);