修改分包接收前板发的YUV数据,取图成功后保存YUV图和JPG图
This commit is contained in:
@@ -13,6 +13,85 @@ void yuvToRgb(int y, int u, int v, int& r, int& g, int& b)
|
||||
b = qBound(0, b, 255);
|
||||
}
|
||||
|
||||
// 将 QImage 数据转换为 YUV422
|
||||
QByteArray convertQImageToYUV422(const QImage& image)
|
||||
{
|
||||
int width = image.width();
|
||||
int height = image.height();
|
||||
QByteArray yuvData;
|
||||
yuvData.resize(width * height * 2); // YUV422: 每个像素2字节
|
||||
|
||||
int index = 0;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; x += 2) {
|
||||
QRgb pixel0 = image.pixel(x, y);
|
||||
QRgb pixel1 = image.pixel(x + 1, y);
|
||||
|
||||
int r0 = qRed(pixel0);
|
||||
int g0 = qGreen(pixel0);
|
||||
int b0 = qBlue(pixel0);
|
||||
|
||||
int r1 = qRed(pixel1);
|
||||
int g1 = qGreen(pixel1);
|
||||
int b1 = qBlue(pixel1);
|
||||
|
||||
// 计算YUV值
|
||||
int y0 = (0.299 * r0 + 0.587 * g0 + 0.114 * b0);
|
||||
int u = (-0.169 * r0 - 0.331 * g0 + 0.5 * b0 + 128);
|
||||
int y1 = (0.299 * r1 + 0.587 * g1 + 0.114 * b1);
|
||||
int v = (0.5 * r0 - 0.419 * g0 - 0.081 * b0 + 128);
|
||||
|
||||
yuvData[index++] = static_cast<char>(qBound(0, y0, 255));
|
||||
yuvData[index++] = static_cast<char>(qBound(0, u, 255));
|
||||
yuvData[index++] = static_cast<char>(qBound(0, y1, 255));
|
||||
yuvData[index++] = static_cast<char>(qBound(0, v, 255));
|
||||
}
|
||||
}
|
||||
|
||||
return yuvData;
|
||||
}
|
||||
|
||||
// 将 QImage 数据转换为 YUV420
|
||||
QByteArray convertQImageToYUV420(const QImage& image)
|
||||
{
|
||||
int width = image.width();
|
||||
int height = image.height();
|
||||
QByteArray yuvData;
|
||||
int ySize = width * height;
|
||||
int uvSize = (width / 2) * (height / 2);
|
||||
yuvData.resize(ySize + 2 * uvSize); // Y 分量 + U 分量 + V 分量
|
||||
|
||||
int yIndex = 0;
|
||||
int uIndex = ySize;
|
||||
int vIndex = ySize + uvSize;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
QRgb pixel = image.pixel(x, y);
|
||||
|
||||
int r = qRed(pixel);
|
||||
int g = qGreen(pixel);
|
||||
int b = qBlue(pixel);
|
||||
|
||||
// 计算 YUV 值
|
||||
int Y = qBound(0, static_cast<int>(0.299 * r + 0.587 * g + 0.114 * b), 255);
|
||||
int U = qBound(0, static_cast<int>(-0.169 * r - 0.331 * g + 0.5 * b + 128), 255);
|
||||
int V = qBound(0, static_cast<int>(0.5 * r - 0.419 * g - 0.081 * b + 128), 255);
|
||||
|
||||
// 填充 Y 分量
|
||||
yuvData[yIndex++] = static_cast<char>(Y);
|
||||
|
||||
// 对 U 和 V 分量进行抽样
|
||||
if (y % 2 == 0 && x % 2 == 0) {
|
||||
yuvData[uIndex++] = static_cast<char>(U);
|
||||
yuvData[vIndex++] = static_cast<char>(V);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return yuvData;
|
||||
}
|
||||
|
||||
// 将 YUV422 数据转换为 QImage
|
||||
QImage convertYUV422ToQImage(const QByteArray& yuv422Data, int width, int height)
|
||||
{
|
||||
@@ -72,29 +151,21 @@ QImage convertYUV420ToQImage(const QByteArray& yuv420Data, int width, int height
|
||||
return image;
|
||||
}
|
||||
|
||||
void showPic(QLabel* leftLens_m_imageLabel, QLabel* rightLens_m_imageLabel, const QString& client, const QByteArray& valData)
|
||||
void DataHandler::showPic(QSize labelSize, int lens_n,
|
||||
int width, int height, int format, const QByteArray* valData)
|
||||
{
|
||||
int lens_n = static_cast<unsigned char>(valData[0]);
|
||||
int width = (static_cast<unsigned char>(valData[2]) << 8) | static_cast<unsigned char>(valData[1]);
|
||||
int height = (static_cast<unsigned char>(valData[4]) << 8) | static_cast<unsigned char>(valData[3]);
|
||||
int format = static_cast<unsigned char>(valData[5]);
|
||||
qDebug() << "lens_n = " << lens_n;
|
||||
qDebug() << "format = " << format;
|
||||
qDebug() << "width = " << width;
|
||||
qDebug() << "height = " << height;
|
||||
|
||||
QByteArray yuvData = valData.mid(6);
|
||||
qDebug() << "yuvData size = " << yuvData.size();
|
||||
//QByteArray yuvData = valData.mid(6);
|
||||
qDebug() << "yuvData size = " << valData->size();
|
||||
|
||||
QImage image;
|
||||
if (format == YUV422) {
|
||||
image = convertYUV422ToQImage(yuvData, width, height);
|
||||
image = convertYUV422ToQImage(*valData, width, height);
|
||||
}
|
||||
else if (format == YUV420) {
|
||||
image = convertYUV420ToQImage(yuvData, width, height);
|
||||
image = convertYUV420ToQImage(*valData, width, height);
|
||||
}
|
||||
else {
|
||||
qWarning() << "Unsupported image format!";
|
||||
qWarning() << "Unsupported image format! Please use YUV422 or YUV420 format";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -103,16 +174,48 @@ void showPic(QLabel* leftLens_m_imageLabel, QLabel* rightLens_m_imageLabel, cons
|
||||
transform.rotate(90); // 可以调整旋转角度
|
||||
QImage rotatedImage = image.transformed(transform);
|
||||
|
||||
QImage scaledImage = rotatedImage.scaled(leftLens_m_imageLabel->size(), Qt::KeepAspectRatio);
|
||||
QImage scaledImage = rotatedImage.scaled(labelSize, Qt::KeepAspectRatio);
|
||||
QPixmap pixmap = QPixmap::fromImage(scaledImage);
|
||||
if (lens_n == 0) {
|
||||
leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
//rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
//leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
emit updateLeftLensImage(pixmap);
|
||||
}
|
||||
else if (lens_n == 1) {
|
||||
rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
//rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
emit updateRightLensImage(pixmap);
|
||||
}
|
||||
else {
|
||||
qWarning() << "Unsupported image lens!";
|
||||
}
|
||||
|
||||
// 生成保存图片的目录
|
||||
QString saveDirPath = QDir::currentPath() + "/frontBoardImage";
|
||||
QDir saveDir(saveDirPath);
|
||||
if (!saveDir.exists()) {
|
||||
saveDir.mkpath(saveDirPath);
|
||||
}
|
||||
QString currentTime = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
|
||||
QByteArray rotatedYuvData;
|
||||
if (format == YUV422) {
|
||||
rotatedYuvData = convertQImageToYUV422(rotatedImage);
|
||||
}
|
||||
else if (format == YUV420) {
|
||||
rotatedYuvData = convertQImageToYUV420(rotatedImage);
|
||||
}
|
||||
QString yuvFileName = saveDirPath + "/" + currentTime + ".yuv";
|
||||
QFile yuvFile(yuvFileName);
|
||||
if (yuvFile.open(QIODevice::WriteOnly)) {
|
||||
yuvFile.write(rotatedYuvData);
|
||||
yuvFile.close();
|
||||
qDebug() << "YUV image saved to" << yuvFileName;
|
||||
}
|
||||
else {
|
||||
qWarning() << "Failed to save rotated YUV image to" << yuvFileName;
|
||||
}
|
||||
|
||||
// 额外:可以保存旋转后的图像为JPG或PNG格式
|
||||
QString rotatedImageFileName = saveDirPath + "/" + currentTime + ".jpg";
|
||||
rotatedImage.save(rotatedImageFileName, "JPG");
|
||||
qDebug() << "JPG image saved to" << rotatedImageFileName;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
#include <QLabel>
|
||||
#include <QDebug>
|
||||
|
||||
#include "../RecvDataHandler/RecvDataHandler.h"
|
||||
|
||||
#define YUV420 1
|
||||
#define YUV422 2
|
||||
|
||||
// YUV 转换为 RGB 的辅助函数
|
||||
void yuvToRgb(int y, int u, int v, int& r, int& g, int& b);
|
||||
|
||||
QByteArray convertQImageToYUV422(const QImage& image);
|
||||
QByteArray convertQImageToYUV420(const QImage& image);
|
||||
// 转换YUV422
|
||||
QImage convertYUV422ToQImage(const QByteArray& yuv422Data, int width, int height);
|
||||
QImage convertYUV420ToQImage(const QByteArray& yuv420Data, int width, int height);
|
||||
|
||||
// 显示图片和视频的函数
|
||||
void showPic(QLabel* leftLens_m_imageLabel, QLabel* rightLens_m_imageLabel, const QString& client, const QByteArray& valData);
|
||||
//void showVideo(QLabel* videoLabel, const QString& client, const QByteArray& valData);
|
||||
|
||||
#endif // MEDIA_H
|
||||
|
||||
@@ -11,16 +11,16 @@ FFmpegDecoder::FFmpegDecoder(QObject* parent) :
|
||||
frame(nullptr),
|
||||
packet(nullptr),
|
||||
swsContext(nullptr),
|
||||
videoStreamIndex(-1) // 初始化成员变量
|
||||
videoStreamIndex(-1)
|
||||
{
|
||||
av_log_set_level(AV_LOG_QUIET); // 设置日志级别为安静模式
|
||||
avformat_network_init(); // 初始化网络
|
||||
qDebug() << "FFmpegDecoder created";
|
||||
qDebug() << "FFmpegDecoder thread created";
|
||||
}
|
||||
|
||||
FFmpegDecoder::~FFmpegDecoder()
|
||||
{
|
||||
qDebug() << "Destroying FFmpegDecoder";
|
||||
qDebug() << "Destroying FFmpegDecoder thread";
|
||||
mutex.lock();
|
||||
abort = true;
|
||||
condition.wakeOne();
|
||||
@@ -28,7 +28,7 @@ FFmpegDecoder::~FFmpegDecoder()
|
||||
wait();
|
||||
cleanup();
|
||||
avformat_network_deinit(); // 反初始化网络
|
||||
qDebug() << "FFmpegDecoder destroyed";
|
||||
qDebug() << "FFmpegDecoder thread destroyed";
|
||||
}
|
||||
|
||||
void FFmpegDecoder::processVideo(int itemIndex)
|
||||
@@ -72,7 +72,7 @@ void FFmpegDecoder::stopFFmpegDecoder()
|
||||
{
|
||||
mutex.lock();
|
||||
abort = true;
|
||||
condition.wakeOne(); // 唤醒等待的线程
|
||||
condition.wakeOne();
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -134,10 +134,8 @@ void FFmpegDecoder::run()
|
||||
if (currentFileSize > fileSize) {
|
||||
fileSize = currentFileSize;
|
||||
file.seek(fileSize); // 设置文件读取位置到末尾
|
||||
//qDebug() << "---------------1---------------";
|
||||
// 读取并处理数据包
|
||||
while (av_read_frame(formatContext, packet) >= 0) {
|
||||
//qDebug() << "---------------2---------------";
|
||||
if (packet->stream_index == videoStreamIndex) {
|
||||
int ret = avcodec_send_packet(codecContext, packet);
|
||||
if (ret < 0) {
|
||||
@@ -145,7 +143,6 @@ void FFmpegDecoder::run()
|
||||
av_packet_unref(packet);
|
||||
continue;
|
||||
}
|
||||
//qDebug() << "---------------3---------------";
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(codecContext, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
@@ -156,31 +153,23 @@ void FFmpegDecoder::run()
|
||||
qWarning() << "Error during decoding";
|
||||
break;
|
||||
}
|
||||
//qDebug() << "---------------4---------------";
|
||||
QImage img = avFrameToQImage(frame);
|
||||
//qDebug() << "---------------5---------------";
|
||||
QImage scaledImage = img.scaled(labelSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
//qDebug() << "---------------6---------------";
|
||||
currentVideoLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
QThread::msleep(10); // Simulate 25 FPS frame rate
|
||||
//qDebug() << "---------------7---------------";
|
||||
}
|
||||
}
|
||||
av_packet_unref(packet);
|
||||
//qDebug() << "---------------8---------------";
|
||||
}
|
||||
}
|
||||
//qDebug() << "---------------9---------------";
|
||||
mutex.lock();
|
||||
if (restart) {
|
||||
restart = false;
|
||||
mutex.unlock();
|
||||
break;
|
||||
}
|
||||
//qDebug() << "---------------10---------------";
|
||||
mutex.unlock();
|
||||
}
|
||||
//qDebug() << "---------------11---------------";
|
||||
cleanup();
|
||||
file.close();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user