以下是一个简单的例子,展示了如何在单独的线程中渲染YUV图像并将其显示到GUI界面上:
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
#include <QImage>
class YuvRenderer : public QObject
{
Q_OBJECT
public:
void renderYuv(const uchar *yData, const uchar *uData, const uchar *vData,
int width, int height);
signals:
void yuvRendered(QImage image);
};
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void onNewFrameReceived(const uchar *yData, const uchar *uData,
const uchar *vData, int width, int height);
void onYuvRendered(QImage image);
private:
Ui::MainWindow *ui;
QThread thread;
YuvRenderer renderer;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Move the renderer object to a separate thread and start it.
renderer.moveToThread(&thread);
connect(&thread, &QThread::finished, &renderer, &QObject::deleteLater);
// connect(&renderer, &YuvRenderer::yuvRendered, this, &MainWindow::onYuvRendered);
thread.start();
}
MainWindow::~MainWindow()
{
thread.quit();
thread.wait();
delete ui;
}
void MainWindow::onNewFrameReceived(const uchar *yData, const uchar *uData,
const uchar *vData, int width, int height)
{
QMetaObject::invokeMethod(&renderer, "renderYuv", Qt::QueuedConnection,
Q_ARG(const uchar*, yData),
Q_ARG(const uchar*, uData),
Q_ARG(const uchar*, vData),
Q_ARG(int, width),
Q_ARG(int, height));
}
void MainWindow::onYuvRendered(QImage image)
{
ui->label->setPixmap(QPixmap::fromImage(image));
}
void YuvRenderer::renderYuv(const uchar *yData, const uchar *uData,
const uchar *vData, int width, int height)
{
// Convert YUV to RGB and create a QImage object.
QImage image(width, height, QImage::Format_RGB888);
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
// Get the YUV values of the current pixel.
int y = yData[i*width + j];
int u = uData[(i/2)*(width/2) + (j/2)];
int v = vData[(i/2)*(width/2) + (j/2)];
// Convert YUV to RGB.
int r = qBound(0, y + 1.4075*(v-128), 255);
int g = qBound(0, y - 0.3455*(u-128) - 0.7169*(v-128), 255);
int b = qBound(0, y + 1.7790*(u-128), 255);
// Set the RGB values of the current pixel in the QImage.
image.setPixel(j, i, qRgb(r, g, b));
}
}
// Emit the yuvRendered signal with the resulting image.
emit yuvRendered(image);
}
其中,MainWindow类是GUI界面的主窗口,它创建了一个YuvRenderer对象,并将其移动到一个单独的QThread线程中。当新的一帧YUV图像数据到达时,MainWindow类会调用YuvRenderer对象的renderYuv方法,在该方法中将YUV图像转换为RGB格式并创建QImage对象,最后通过信号yuvRendered将渲染结果发送回主线程进行显示。
注意:这里省略了对于输入参数的检查和异常处理等细节。在实际应用中需要根据具体情况进行处理。