Qt之显示yuv数据图像

12 篇文章 0 订阅

来自:http://blog.csdn.net/x348722662/article/details/53445136

本文对在QT中实时显示yuv数据提供一个解决方案,再次特别非常感谢http://blog.yundiantech.com/中的博文,也是借鉴其中的播放YUV文件的demo实现实时播放yuv视频数据,废话不多说,就直接介绍显示效果最好的方法吧

  • qt中利用mmfpeg将yuv转RGB32
  • qt中将rbg显示到label上

qt中利用mmfpeg将yuv转RGB32

因为在QT中是无法直接显示yuv数据,所以我们必须把yuv数据转换成RGB32通过QImage来显示到控件中,具体的yuv和rgb的基本介绍就不在此给大家做介绍,需要知道原理的自行百度,如果想自己通过写转换代码来实现,也是可以的,只不过转换出来的效果不是太理想,特别是在纯白的背景时候,会有纯红,纯绿,纯蓝的颜色出现,导致整个颜色的偏差,所以我们直接采用mmfpeg中的yuv转rgb的方法,优化和效率都不错。

extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
}
uint8_t *yuvBuffer;
AVFrame *pFrame ;
AVFrame *pFrameRGB;
uint8_t * rgbBuffer;
SwsContext *img_convert_ctx;

//初始化
void InitPlay(int width,int height)
{
    //width和heigt为传入的分辨率的大小,实际应用我传的1280*720
    int yuvSize = width * height * 3 /2;
    yuvBuffer = (uint8_t *)malloc(yuvSize);
    //为每帧图像分配内存
    pFrame = av_frame_alloc();
    pFrameRGB = av_frame_alloc();
    int numBytes = avpicture_get_size(PIX_FMT_RGB32, width,height);
    rgbBuffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
    avpicture_fill((AVPicture *) pFrameRGB, rgbBuffer, PIX_FMT_RGB32,width, height);
    //特别注意 img_convert_ctx 该在做H264流媒体解码时候,发现sws_getContext /sws_scale内存泄露问题,
    //注意sws_getContext只能调用一次,在初始化时候调用即可,另外调用完后,在析构函数中使用sws_free_Context,将它的内存释放。
    //设置图像转换上下文
    img_convert_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P, width, height, PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
 }
 //实时接收yuv数据转换成rgb32 str是yuv数据,len为长度
 void wb_yuv(void* str,int len)
{
    avpicture_fill((AVPicture *) pFrame, (uint8_t *)str, AV_PIX_FMT_YUV420P, width, height);//这里的长度和高度跟之前保持一致
    //转换图像格式,将解压出来的YUV420P的图像转换为RGB的图像
    sws_scale(img_convert_ctx,
            (uint8_t const * const *) pFrame->data,
            pFrame->linesize, 0, height, pFrameRGB->data,
            pFrameRGB->linesize);
    //把这个RGB数据 用QImage加载
    QImage tmpImg((uchar *)rgbBuffer,mWidth,mHeight,QImage::Format_RGB32);
    QImage image = tmpImg.copy(); //把图像复制一份 传递给界面显示
    emit sig_GetOneFrame(image);  //发送信号,将次imamge发送到要显示的控件,用paintEvent绘制出来

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

qt中将RGB32显示到label上

继承了一个QLbel的类,重写paintEvent事件,将RBG绘制到界面中

//接收sig_GetOneFrame信号,调用update在界面中显示图像
void DecLabel::slotGetOneFrame(QImage img)
{
    wb_Image = img;
    update(); //调用update将执行 paintEvent函数
}
//需要重写paintEvent事件
void DecLabel::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    if (wb_Image.size().width() <= 0) return;
    ///将图像按比例缩放成和窗口一样大小
     QImage img = wb_Image.scaled(this->size,Qt::IgnoreAspectRatio);
     int x = this->width() - img.width();
     int y = this->height() - img.height();
     painter.drawImage(QPoint(x,y),img); //画出图像

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

小结:实际应用中,因为我们有自己的解码库,将实时的H.264数据解码成YUV数据,但需要自己做显示,就借鉴FFMPEG中YUV转RGB32方法,实现之后效果还不错。

### 回答1: 在Qt显示YUV数据可以通过使用QImage类来实现。 首先,需要创建一个QImage对象用于存储YUV数据YUV数据是一种颜色编码格式,分为Y分量(亮度)和UV分量(色度),通常以3个连续的平面存储。因此,需要将YUV数据转换为RGB格式,才能在Qt中进行显示。可以使用FFmpeg等库来进行YUV到RGB的转换操作。 接下来,可以使用QImage的setPixel函数来设置每个像素的值。循环遍历YUV数据的每个像素,依次计算对应的RGB值,并使用setPixel函数设置对应的像素值。 最后,将QImage对象显示到窗口上。可以使用QLabel或者QPainter来绘制图像。对于使用QLabel,可以使用其setPixmap函数将QImage对象设置为其显示图像。对于使用QPainter,可以使用其drawImage函数来在绘图区域绘制QImage对象。 此外,还可以在显示过程中对图像进行缩放、裁剪、旋转等操作。可以使用QImage的scaled、copy和transformed函数来实现相应功能。 综上所述,通过以上方法可以在Qt显示YUV数据。 ### 回答2: Qt是一个功能强大的跨平台应用程序开发框架,可以用于开发图形界面应用程序。在Qt显示YUV数据需要进行以下步骤: 1. 首先,需要创建一个Qt的窗口组件,用于显示YUV数据。可以使用QWidget或QLabel等组件。 2. 接下来,需要将YUV数据格式转换为Qt支持的RGB格式。可以使用OpenCV库或Qt自带的相关函数进行转换。 3. 创建一个QImage对象,并使用转换后的RGB数据填充该对象。可以使用QImage的setPixel函数或者使用QImage构造函数直接传入数据。 4. 将QImage对象绘制到窗口组件上。可以使用QWidget的paintEvent函数中的QPainter对象将QImage绘制出来。 以下是一个简单的示例代码: ``` // 创建一个显示YUV数据的窗口组件 QWidget *widget = new QWidget(); // 将YUV数据转换为RGB格式 // 这里假设已经有了转换后的RGB数据,存储在rgbData中 // 创建QImage对象,并使用转换后的RGB数据填充 QImage image(rgbData, width, height, QImage::Format_RGB888); // 在窗口组件上绘制QImage对象 void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawImage(0, 0, image); } ``` 通过上述步骤,就可以在Qt显示YUV数据了。注意,以上代码是一个简单示例,实际使用中可能需要根据具体需求进行相应的修改和优化。 ### 回答3: Qt是一个跨平台的图形用户界面应用程序开发框架,可以用于开发各种类型的应用程序。如果要在Qt显示YUV数据,可以采取以下步骤: 1. 首先,需要将原始的YUV数据转换为Qt可以理解的图像格式,例如RGB格式。可以使用各种转换算法来实现这一步骤,比如将Y、U和V三个分量合成为RGB图像。 2. 一旦将YUV数据转换为RGB格式,可以使用Qt中提供的图像处理类来创建一个QImage对象。QImage是Qt中表示图像的类,可以用于存储和处理图像数据。 3. 接着,可以将QImage对象显示Qt的窗口中。可以使用Qt中的QWidget、QLabel或者QGraphicsView等控件,将QImage对象作为控件的背景图像显示出来。可以通过设置控件的属性或使用API来实现图像显示。 4. 如果要实现实时显示YUV数据,可以将以上步骤封装在一个循环中,并将YUV数据不断传入进行处理和显示。可以使用Qt的定时器或者多线程来实现数据的实时获取和处理。 需要注意的是,YUV数据的格式可能存在不同的变种,如YUV420、YUV422、YUV444等。在实际显示时,需要根据具体的数据格式来进行相应的转换和处理。此外,由于YUV数据是一种压缩格式,其显示效果可能与RGB格式有所不同,所以在显示时可能需要进行一些补偿或调整以获得更好的图像质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值