一湾碎、QT實現(xiàn)截屏為QImage;
這個相對來說網(wǎng)上資料比較多宙攻!
#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
); //調(diào)整圖像大小為1024×768
QImage disktop=disktop_img.toImage(); //轉(zhuǎn)換為QImage
//RGBA 32位轉(zhuǎn)換為RGB 24位
QImage disktop= disktop.convertToFormat(QImage::Format_RGB888);
}
二、實現(xiàn)QImage轉(zhuǎn)YUV:4:2:0
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組成邓馒。
yuv是由灰度數(shù)據(jù)+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的數(shù)據(jù)列表;
2缤言、U:每隔一行并且為奇數(shù)時計算一個U值存到U的列表中;
3、V:每隔一行并且為奇數(shù)時計算一個U值存到V的列表中;
Y的算法:0.299R+0.587G+0.114B;
U的算法:-0.169R-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轉(zhuǎn)為rgb,也就是上面提到的rgb24;
disktop= disktop.convertToFormat(QImage::Format_RGB888);
//rgb 轉(zhuǎn) yuv 4:2:0
QByteArray y_l,u_l,v_l,yuv; //Y ,U,V
uchar * d=disktop.bits(); //截屏QImage的數(shù)據(jù)
//循環(huán)變量
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++){ //遍歷當(dāng)前行的所有像素.
int pos=i*(width*3)+j*3; //行號*行寬=已遍歷行的數(shù)據(jù)+這一行的第幾個像素,3表示:一個像素占3個bit
//一個像素的數(shù)據(jù)格式:[B,G,R]
r=d[pos+2]; //取出當(dāng)前像素的R
g=d[pos+1]; //取出當(dāng)前像素的G
b=d[pos]; //取出當(dāng)前像素的B
y=0.299*r+0.587*g+0.114*b; //根據(jù)公式求出Y的值
y_l.append(y); //把值壓入Y的Bytearray;
if(i%2==0 and j%2==0){ // 偶數(shù)行并且偶數(shù)像素(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
}
//驗證轉(zhuǎn)換是否成功
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(); //調(diào)用截屏返回[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();
}
}
yuview 播放器
Overview.png