vs2019+Qt 使用 Qlabel 在界面上显示图像及显示失真问题

10 篇文章 4 订阅
8 篇文章 2 订阅

        在使用 Qt 设计界面时,通常会涉及到在界面上显示图片的问题,而要在界面上显示图片需要使用控件 Qlabel 和 函数 QImage ,下面对控件和函数逐一做出介绍!!!

一、Qlabel 常见成员方法

1、setText(const QString &text)  --------------  设置显示文本

2、void setAlignment(Qt::Alignment)  --------------  设置文本显示位置

3、void setFont(const QFont &)  --------------  设置字体

4、void setPixmap(const QPixmap &)  --------------  设置图片

5、void setMovie(QMovie *movie)  --------------  设置动图


二、QImage 函数介绍

1、QImage 函数基本定义:

QImage(uchar * data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction = 0, void * cleanupInfo = 0)

2、QImage 函数形参介绍 

(1)data 直接使用 Mat 类型的 data 即可,如:image.data;

(2)width 表示图像的宽,即图像的列;

(3)height表示高,即图像的宽;

(4)bytesPerline 表示每行拥有的字节数(如果没有该参数则默认按照 4 字节对齐的方式显示,见另个构造函数);

(5)format 表示图片格式,彩色图一般采用Format_RGB888,灰度图则使用Format_indexed8;

注意:bytesPerline 参数如果设置不当可能会导致图片显示失真,见下图;

  图 1 原图 

图 2 显示失真


 三、代码和结果

1、代码实现

cv::Mat image = cv::imread("D:\\image.png");//要显示的影像

cvtColor(image, image, CV_BGR2RGB);			//转换色彩空间,把RGB转为BGR

//把 Mat 转换成 QImage
QImage img_1 = QImage((const unsigned char*)(image.data), image.cols, image.rows, image.cols * image.channels(), QImage::Format_RGB888);

ui.label->setPixmap(QPixmap::fromImage(img_1));

//设定 Label 尺寸
ui.label->resize(QSize(img_1.width(), img_1.height()));

说明:cv::Mat 存储图像通道顺序为:RGB,而 QImage 存储图像通道顺序为:BGR,所以在显示前需要进行通道上的转换!

2、显示结果

说明:QImage 函数中,如果 bytesPerline 参数不设置,则会默认按照 4 字节对齐的方式显示图像(如果不满足四字节对齐要求则不会使用零填充),对于不满足四字节对齐的影像在显示的时候就会出现上述失真问题,若将 bytesPerline 参数设置为 image.cols*image.channels() (如上述代码所示)则可解决图像显示失真问题(如上图显示结果)!!!


四、四字节对齐原理

        如果图像没有做字节对齐,则在对图像进行逐像素遍历的时候会出现差错,也即图像的失真。而 Opencv 中 Mat 矩阵的创建通常是默认没有字节对齐的,所以,如果使用 QImage 对 Mat矩阵进行显示需要进行字节对齐处理!

        每个像素所占字节数等于图像通道数,也即一个像素占 3 个字节(常规图像为三通道);本次实验案例使用的图像尺寸为:5528*3857 ,3857 为行、5528 为列,所以一行图像数据所占字节数为:5528*3 字节。

        所谓四字节对齐即看 5528*3 是否是 4 的整数倍,如果不是则需要使用零对其补齐,方能正常显示图像,而 QImage 函数中,如果不对 bytesPerline 参数设置,则默认以四字节对齐的方式显示图像,且对不满足四字节对齐的不使用零补充;如果把 bytesPerline 参数设置为 image.cols * image.channels() 即设置不满足四字节对齐时使用零补充,然后在显示不满足四字节对齐的图像时,方能正常显示。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 采用Qt库在QLabel控件上显示图片并在图片上画直线的实现步骤如下: 1. 创建一个QLabel控件,并设置其大小和位置。 ```cpp QLabel* label = new QLabel(this); label->setGeometry(0, 0, 300, 300); ``` 2. 加载图片并设置为QLabel的背景。 ```cpp QPixmap pixmap(":/image/image.png"); // 从资源文件加载图片 QPalette palette; palette.setBrush(label->backgroundRole(), QBrush(pixmap)); label->setPalette(palette); label->setAutoFillBackground(true); ``` 3. 在QLabel上创建一个QPainter对象,并设置画笔的颜色、宽度等属性。 ```cpp QPainter painter(label); painter.setPen(QPen(Qt::red, 2)); // 设置画笔为红色,宽度为2 ``` 4. 使用QPainter在图片上绘制直线。 ```cpp painter.drawLine(50, 50, 250, 250); // 在图片上绘制一条从(50, 50)到(250, 250)的直线 ``` 5. 更新QLabel控件以显示绘制好的图片。 ```cpp label->update(); ``` 完整代码如下所示: ```cpp #include <QtWidgets> int main(int argc, char *argv[]) { QApplication a(argc, argv); // 创建主窗体 QWidget window; window.setWindowTitle("Qt Display Image"); window.resize(300, 300); // 创建QLabel控件 QLabel* label = new QLabel(&window); label->setGeometry(0, 0, 300, 300); // 加载图片并设置为QLabel的背景 QPixmap pixmap(":/image/image.png"); // 从资源文件加载图片 QPalette palette; palette.setBrush(label->backgroundRole(), QBrush(pixmap)); label->setPalette(palette); label->setAutoFillBackground(true); // 在QLabel上创建一个QPainter对象,并设置画笔的颜色、宽度等属性 QPainter painter(label); painter.setPen(QPen(Qt::red, 2)); // 设置画笔为红色,宽度为2 // 使用QPainter在图片上绘制直线 painter.drawLine(50, 50, 250, 250); // 在图片上绘制一条从(50, 50)到(250, 250)的直线 // 更新QLabel控件以显示绘制好的图片 label->update(); window.show(); return a.exec(); } ``` 以上代码演示了如何使用QtQLabel显示图片并在图片上绘制直线。图片加载部分使用了资源文件的方式,即图片需要事先添加到Qt的资源文件。 ### 回答2: 在Qt,要在QLabel显示图片并在图片上画直线,您可以按照以下步骤进行操作: 1. 创建一个QLabel对象,并将其设置为一个窗口部件(Widget)的子部件,使用QVBoxLayout进行布局。 ```cpp QLabel *label = new QLabel(this); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(label); this->setLayout(layout); ``` 2. 加载图片到QPixmap对象,并将其设置到QLabel进行显示。 ```cpp QPixmap pixmap("image.png"); label->setPixmap(pixmap); label->setScaledContents(true); // 自适应QLabel的大小 ``` 3. 创建一个QPainter对象来绘制直线。可以在QLabel的paintEvent事件函数绘制直线。 ```cpp void MyWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.drawPixmap(label->geometry(), pixmap); // 在QLabel的范围内绘制图片 // 绘制直线 painter.setPen(Qt::red); // 设置直线颜色为红色 painter.drawLine(50, 50, 200, 200); // 在图片上画一条直线,起点(50, 50),终点(200, 200) } ``` 这样,您就可以在QtQLabel显示图片并在图片上绘制直线了。希望对您有所帮助! ### 回答3: 在Qt,要在QLabel显示图片并在图片上画直线,可以通过以下步骤实现: 1. 创建一个QLabel控件,并设置其大小和位置。 ```cpp QLabel *label = new QLabel(this); label->setGeometry(10, 10, 500, 500); ``` 2. 从文件加载图片,并将其设置为QLabel的背景。 ```cpp QPixmap pixmap("image.jpg"); label->setPixmap(pixmap); ``` 3. 在QLabel上添加一个QPainter对象,并设置其渲染目标为QLabel。 ```cpp QPainter painter(label); ``` 4. 使用QPen设置画笔的颜色、宽度等属性。 ```cpp QPen pen(Qt::red); pen.setWidth(2); painter.setPen(pen); ``` 5. 使用QPainter在图片上画直线。 ```cpp painter.drawLine(10, 10, 300, 300); ``` 这将在图片上从点(10, 10)绘制一条直线到点(300, 300)。 6. 结束绘制并更新QLabel显示。 ```cpp painter.end(); label->update(); ``` 通过以上步骤,你可以在QtQLabel控件上显示图片并在图片上画直线。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据库内核

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值