同时安装了两个操作系统,一模一样的代码,在其中一个官网下载的win10系统中是运行没有问题的,代码如下,
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);
}
}
但是,在我的另一个Ghost Win10的系统中, img = QImage::fromData(frame.bits(), nbytes); 返回的一直是invalid,无法获取正常的图像;
有人改写成下面的样子(原文链接:https://blog.csdn.net/jack_20/article/details/106735523),
bool present(const QVideoFrame &frame)
{
if (frame.isValid()) {
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
int format= QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat());
if (format != QImage::Format_Invalid)
{
QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
cloneFrame.bytesPerLine(),
format);
//do something
}
else {
if (cloneFrame.pixelFormat() == QVideoFrame::Format_YUYV)
{
int nbytes = cloneFrame.mappedBytes();
char *rgb24 = new char[nbytes*2]();
convert_yuv_to_rgb_buffer((unsigned char*)cloneFrame.bits(), (unsigned char*)rgb24, cloneFrame.width(), cloneFrame.height());
//不用QT的话,这里可以直接把图片rgb24buffer写入文件image.bmp中,
//注意保存格式,bmp是位图,而类似jpg,png之类的是经压缩过的。
QImage img((unsigned char*)rgb24, cloneFrame.width(), cloneFrame.height(), cloneFrame.width()*3, QImage::Format_RGB888);
emit frameAvailable(img);
delete[] rgb24;
}
else
{
int nbytes = cloneFrame.mappedBytes();
QImage image = QImage::fromData(cloneFrame.bits(), nbytes);
emit frameAvailable(image);
}
}
cloneFrame.unmap();
return true;
}
return false;
}
测试了一下,发现Ghost系统中格式确实是QVideoFrame::Format_YUYV,但网上的convert_yuv_to_rgb_buffer函数容易出错,一时也没时间研究,只好在这做个记录。
解决办法:
因为我使用的Qt版本是5.15.2,所以在这个Ghost的win10系统中,最后使用了下面的代码,
// valid only for Qt > v5.15...
const QVideoFrame frame(buffer); // make a copy we can call map (non-const) on
QImage image = frame.image(); // This function was introduced in Qt 5.15.
//QImage::Format ifmt = image.format();
//qDebug() << ifmt;
return image;
这样可以获取正确的图像。
参考资料:
https://spacevision.blog.csdn.net/article/details/125300108
https://blog.csdn.net/u011942101/article/details/126917796
https://blog.csdn.net/u011942101/article/details/115278753