Qt图片自适应控件大小
Qt5.12.0 + opencv344
目的
主要是想让打开的视频可以自适应窗口大小,放大或者缩小窗口时视频图片也可以跟着放大缩小。
最初的使用方法
- 使用QLabel
- QLbale置于QWidget中
- 对QWidget使用 栅格布局
部分代码如下:
//方法一
//直接显示
QImage image = MatToQImage2(mat);
QPixmap pixmap = QPixmap::fromImage(image);
ui->label_image->setPixmap(pixmap);
//方法二
//按比例缩放
QImage image=MatToQImage2(mat);
QPixmap pixmap = QPixmap::fromImage(image);
int width = ui->label_image->width();
int height = ui->label_image->height();
QPixmap fitpixmap = pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); //按比例缩放
ui->label_image->setPixmap(fitpixmap);
显示效果
存在问题
- 方法一:图片大小不会随着窗口的放大而放大
- 方法二:随着窗口的放大,图片可以很好的自适应放大,显示比例也正常,但放大后不能再调整缩小窗口,相应的图片大小也无法缩小
修改1
方法二中,若对Qwidget设置最小值,如10,则可以任意调整大小???
实测可以,原理暂时不清楚
修改2
参考资料
作者:x264ge
来源:CSDN
原文:https://blog.csdn.net/yh_1988/article/details/6752733
ui->label->setScaledContents(true);//为设置QLabel自动缩放,既:显示图像大小自动调整为Qlabel大小。
//方法三,完全按QWidget缩放,不能保持原比例
QImage image=MatToQImage2(mat);
QPixmap pixmap = QPixmap::fromImage(image);
ui->label_image->resize(ui->widget_show->size());
ui->label_image->setPixmap(pixmap);
存在问题
方法三图片完全按照Qwidget大小缩放,不能保持原视频比例
最终方法
采用方法二,可以使视频按照比例的放大缩小,若想实现不按比例缩放,只需添加ui->label->setScaledContents(true);
完整代码
ui
playvideo.cpp
#include "playvideo.h"
#include "ui_playvideo.h"
playvideo::playvideo(QWidget *parent) :
QWidget(parent),
ui(new Ui::playvideo)
{
ui->setupUi(this);
timer=new QTimer(this);
ui-> label_image->setScaledContents(true);//可以使图片完全按QWidget缩放,而不保持原视频比列
connect(timer,SIGNAL(timeout()),this,SLOT(ReadFrame()));
}
playvideo::~playvideo()
{
delete ui;
}
void playvideo::on_pushButton_open_clicked()
{
videofileName = QFileDialog::getOpenFileName(
this, "open video",
".",
"video (*.avi *.mp4 *.flv));;All files (*.*)");
sfileName = videofileName.toStdString();
video.open(sfileName);
if(!video.isOpened()){
QMessageBox::information(this,tr("提示"),tr("视频没有打开"));
}
else {
int videoW = int( video.get(CV_CAP_PROP_FRAME_WIDTH) );
int videoH = int( video.get(CV_CAP_PROP_FRAME_HEIGHT) );
fps = int( video.get(CV_CAP_PROP_FPS) );
//ui->widget_info->setVisible(true);
//ui->widget_show->setVisible(true);
ui->textBrowser_info->setText(QString("视频信息:%1").arg(videofileName));
ui->textBrowser_info->append(QString("视频尺寸:%2×%3").arg(videoW).arg(videoH));
ui->textBrowser_info->append(QString("视频帧率:%4").arg(fps));
Mat frame_start;
video >> frame_start;
ShowImage(frame_start);
}
}
void playvideo::ShowImage(cv::Mat& mat)
{
//方法二,按比例缩放
QImage image=MatToQImage2(mat);
QPixmap pixmap = QPixmap::fromImage(image);
int width = ui->label_image->width();
int height = ui->label_image->height();
QPixmap fitpixmap = pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
//按比例缩放
ui->label_image->setPixmap(fitpixmap);
}
void playvideo::on_pushButton_play_clicked()
{
timer->start(1000/fps);
}
void playvideo::on_pushButton_pause_clicked()
{
timer->stop();
}
void playvideo::ReadFrame()
{
Mat frame_now;
video >> frame_now;//读帧进frame
if (frame_now.empty())
{
QMessageBox::information(this, tr("warning"), tr("the video is end!"));
timer->stop();
}
else {
ShowImage(frame_now);
}
}
//图像格式转换
QImage playvideo::MatToQImage2(const cv::Mat &mat)
{
QImage img;
int chana = mat.channels();
//依据通道数不同,改变不同的装换方式
if(3 == chana ){
//调整通道次序
cv::cvtColor(mat,mat,CV_BGR2RGB);
img = QImage(static_cast<uchar *>(mat.data),mat.cols,mat.rows,QImage::Format_RGB888);
}
else if(4 == chana )
{
//argb
img = QImage(static_cast<uchar *>(mat.data),mat.cols,mat.rows,QImage::Format_ARGB32);
}
else {
//单通道,灰度图
img = QImage( mat.cols, mat.rows , QImage::Format_Indexed8);
uchar * matdata = mat.data;
for(int row = 0 ; row <mat.rows ; ++row )
{
uchar* rowdata = img.scanLine( row );
memcpy(rowdata,matdata ,mat.cols);
m atdata+=mat.cols;
}
}
return img;
}
playvideo.h
#ifndef playvideo_H
#define playvideo_H
#include <QWidget>
#include <QTimer>
#include <QFileDialog>
#include <QPushButton>
#include <QImage>
#include <QString>
#include <QMessageBox>
#include <QDebug>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
namespace Ui {
class playvideo;
}
class playvideo : public QWidget
{
Q_OBJECT
public:
explicit playvideo(QWidget *parent = nullptr);
~playvideo();
QImage MatToQImage2(const cv::Mat& mat);
void ShowImage(cv::Mat& mat);
private slots:
void on_pushButton_open_clicked();
void on_pushButton_play_clicked();
void ReadFrame();
void on_pushButton_pause_clicked();
private:
Ui::playvideo *ui;
VideoCapture video;
QTimer *timer;
int fps;
QString videofileName;
std::string sfileName;
};
#endif // playvideo_H