• Qt 之 QVideoFrame转换为QImage


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言


    在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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    方法二 依赖opencv

    当方法一的方法行不通时,比如某些特殊的图片格式,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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    方法三,qt5.15版本

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    信息系统项目管理师---第十四章 信息文档管理与配置管理历年考题
    IP地址追踪具体位置:技术和隐私考虑
    java random随机数的用法
    老男孩教育 | 销售转行做网安,完美逆袭,进入国企!
    【网络教程】IPtables官方教程--学习笔记1
    Centos7 安装gdal历程,使用node-gdal功能
    BUUCTF reverse wp 81 - 85
    cmake-format使用教程
    C++ 图片完整性校验
    华为eNSP防火墙USG5500基本配置
  • 原文地址:https://blog.csdn.net/u011942101/article/details/126917796