美文网首页
Qt截屏 X265lib编码 rtsp请求 rtp流发送 (截

Qt截屏 X265lib编码 rtsp请求 rtp流发送 (截

作者: 随你说 | 来源:发表于2019-12-26 16:54 被阅读0次

一、QT实现截屏为QImage;

这个相对来说网上资料比较多!
   #include <QGuiApplication> 
   #include <QPixmap>
   #include <QScreen>
   #include<QImage>
  int main(int argc, char *argv[])
   {
        QScreen *screen= QGuiApplication::primaryScreen(); //获取屏幕接口
        QPixmap disktop_img= screen>grabWindow(0).scaled(
                    1024,768,Qt::IgnoreAspectRatio,Qt::SmoothTransformation
          ); //调整图像大小为1024×768
        QImage disktop=disktop_img.toImage(); //转换为QImage
//RGBA 32位转换为RGB 24位
        QImage  disktop= disktop.convertToFormat(QImage::Format_RGB888);
}

二、实现QImage转YUV:4:2:0

\color{rgb(255,125,125)}{ 什么是RGBA、什么是RGB?这个是理解YUV转换的开始!}
RGBA 是用32位bit来描述一个像素点的,比如宽1024 高768的QImage 实际大小为1024×768×32
一个像素点:8位R、8位的G、8位的B、8位的透明A来组成。
RGB是用24位bit来表示一个像素点的,比如宽1024高768的QImage实际大小为1024×768×24
一个像素点:8位的R、8位的G、8位的B组成。
\color{rgb(255,125,125)}{什么是YUV 4:2:0}
yuv是由灰度数据+U+V
Y的大小为:图片的宽度×图片的高度;
U的大小为:图片的宽度×图片的高度/4;
V的大小为:图片的宽度×图片的高度/4;
也就是说你拿到一个YUV图像你要知道图像的宽度,高度,4:2:0因为YUV图像文件并不携带宽度,高度信息。也只有得到宽度高度才能在文件中切分出Y,U,V的值;
我们需要用下图来理解YUV 4:2:0

yuv.jpg

这是一张宽13像素×13像素的RGB24位的原图。
1、Y:遍历每个像素(uint_8[3])计算出Y的数据列表;
2、U:每隔一行并且为奇数时计算一个U值存到U的列表中;
3、V:每隔一行并且为奇数时计算一个U值存到V的列表中;
Y的算法:0.299R+0.587G+0.114B;
U的算法:-0.169
R-0.331G+0.5B+128;
V的算法:0.5R-0.419G-0.081*G+128

#include<QByteArray>
#include<QList>
#include <QGuiApplication> 
#include <QPixmap>
#include <QScreen>
#include<QImage>
QList<QByteArray>  returnyuv(){ 
 //屏幕
QScreen *screen= QGuiApplication::primaryScreen(); 
//截屏
QPixmap disktop_img= screen->grabWindow(0).scaled(1024,768,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); 
QImage disktop=disktop_img.toImage(); 
//rgba转为rgb,也就是上面提到的rgb24;
disktop= disktop.convertToFormat(QImage::Format_RGB888);
 //rgb  转 yuv 4:2:0
QByteArray y_l,u_l,v_l,yuv; //Y ,U,V
uchar * d=disktop.bits();    //截屏QImage的数据
    //循环变量
    int i,j;
    int width=disktop.width();   //截屏QImage宽
    int height=disktop.height(); //截屏QImage高
    uint8_t r,g,b,y,u,v;            
    for(i=0;i<height;i++){      //遍历截屏QImage的所有行.
        for(j=0;j<width;j++){    //遍历当前行的所有像素.
            int pos=i*(width*3)+j*3;   //行号*行宽=已遍历行的数据+这一行的第几个像素,3表示:一个像素占3个bit
      //一个像素的数据格式:[B,G,R]
            r=d[pos+2]; //取出当前像素的R
            g=d[pos+1]; //取出当前像素的G
            b=d[pos];     //取出当前像素的B
            y=0.299*r+0.587*g+0.114*b;  //根据公式求出Y的值
            y_l.append(y);       //把值压入Y的Bytearray;
            if(i%2==0 and j%2==0){ // 偶数行并且偶数像素(4个像素取1个像素计算出UV)
                u=-0.169*r-0.331*g+0.5*b+128;  //计算出U值
                           u_l.append(u);        //把U值压入U的Bytearray
                v=0.5*r-0.419*g-0.081*b+128;   //计算出V值
                           v_l.append(v);      //把V值压入V的Bytearray
              }
        }
    }
    QList<QByteArray> yuv_byte;  //[Y[Qbytearray],U[Qbytearray],V[Qbytearray]]
    yuv_byte.append(y_l);
    yuv_byte.append(v_l);
    yuv_byte.append(u_l);
    return yuv_byte; //返回yuv
}

//验证转换是否成功
int main(){
    QFile write_file_yuv("./tmp.yuv");
    write_file_yuv.open(QIODevice::WriteOnly);
    if (write_file_yuv.isOpen()){
         QByteArray tmp_file;
        QList<QByteArray> yuv_byte= returnyuv(); //调用截屏返回[y,u,v]
        for(int i=0;i<yuv_byte.length();i++){
            tmp_file.append(yuv_byte[i]);
        }
        write_file_yuv.write(tmp_file); //本地文件存储
        write_file_yuv.flush();
        write_file_yuv.close();
    }
}

\color{rgb(125,125,125)}{使用yuv播放器验证}
yuview 播放器\color{rgb(255,0,0)}{注意:选择格式为yuv 4:2:0,宽度为1024,高为768,yuv图像不带宽高信息,所以你必须知道你图像的大小}

Overview.png
\color{rgb(255,0,0)}{yuv是x265接受的输入方式是不支持rgb,也就是说只有实现了yuv图像才能继续....}

相关文章

网友评论

      本文标题:Qt截屏 X265lib编码 rtsp请求 rtp流发送 (截

      本文链接:https://www.haomeiwen.com/subject/bwlloctx.html