qt-C++笔记之QLabel加载图片
—— 2024-04-06 夜
code review!
文章目录
- qt-C++笔记之QLabel加载图片
- 0.文件结构
- 1.方法一:把图片放在项目路径下,在 .pro 文件中使用 DISTFILES添加图片文件
- 1.1.运行
- 1.2.qt_test.pro
- 1.3.main.cpp
- 2.方法二:不在 .pro 文件中使用 DISTFILES添加图片文件,直接在main.cpp中指定图片路径
- 2.1.main.cpp
- 2.2.附加解释
- 3.方法三:上述方法中直接使用图片去构造QPixmap对象,若使用 QPixmap 的 load() 方法来加载图片
- 3.1.运行
- 3.2.main.cpp
- 3.2.附加解释
- 4.上述代码中只有QLabel和QPixmap,若结合QImage来显示图片
- 4.1.运行
- 4.2.main.cpp
- 4.3.附加解释
- 4.4.代码流程图
- 4.5.`QImage`和`QPixmap`表格对比
- 5.视频流解码的图像数据需要使用的函数:QPixmap::fromImage()
- 6.Qt在加载的图片上的指定位置画矩形框:创建一个 QPainter 实例并在 QPixmap 上绘制矩形
- 6.1.运行
- 6.2.main.cpp
- 7.`setScaledContents`和`scaled`方法表格对比
0.文件结构
1.方法一:把图片放在项目路径下,在 .pro 文件中使用 DISTFILES添加图片文件
1.1.运行
1.2.qt_test.pro
QT += widgets core
TARGET = qt_test
TEMPLATE = app
SOURCES += main.cpp
DISTFILES += \
123.jpg
1.3.main.cpp
#include <QApplication>
#include <QLabel>
#include <QPixmap>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
QPixmap pixmap("123.jpg");
label.setPixmap(pixmap);
label.show();
return app.exec();
}
2.方法二:不在 .pro 文件中使用 DISTFILES添加图片文件,直接在main.cpp中指定图片路径
2.1.main.cpp
#include <QApplication>
#include <QLabel>
#include <QPixmap>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
QPixmap pixmap("/home/user/qt_cpp_test/qt_test/123.jpg"); // 替换为图片文件路径
label.setPixmap(pixmap);
label.show();
return app.exec();
}
2.2.附加解释
QPixmap
是用于处理图像的类,它可以加载和显示许多不同格式的图片。- 使用
QPixmap
的构造函数来加载一个图片文件。 - 使用
QLabel
的setPixmap
方法将图片设置到标签上。 - 最后调用
show
方法来显示带有图片的标签。
确保替换"/path/to/image.jpg"
为实际图片文件的路径。如果图片文件路径不正确或文件不存在,QPixmap
对象将是一个空对象,并且QLabel
不会显示任何图片。
此外,如果图片大小超过QLabel
的大小,那么图片将会被裁剪。如果想让图片自适应QLabel
的大小,可以使用QPixmap::scaled
方法来调整图片尺寸。例如:
label.setPixmap(pixmap.scaled(label.size(), Qt::KeepAspectRatio));
这会将图片缩放到QLabel
的大小,同时保持图片的宽高比。Qt::KeepAspectRatio
是一个枚举值,指示应保持原始图像的宽高比。
3.方法三:上述方法中直接使用图片去构造QPixmap对象,若使用 QPixmap 的 load() 方法来加载图片
3.1.运行
3.2.main.cpp
#include <QApplication>
#include <QLabel>
#include <QPixmap>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
QPixmap pixmap;
// 尝试加载图片,替换为图片文件路径
bool loaded = pixmap.load("123.jpg");
if (loaded) {
// 如果图片加载成功,设置到QLabel
label.setPixmap(pixmap);
} else {
// 如果加载失败,可以设置一个错误消息
label.setText("图片加载失败!");
}
label.show();
return app.exec();
}
3.2.附加解释
使用 QPixmap
的 load()
方法来加载图片,可以先创建一个 QPixmap
对象,然后调用 load()
方法来加载图片文件。这种方式可以方便地检查图片是否成功加载,因为 load()
方法会返回一个布尔值,指示操作是否成功。
在这段代码中:
- 创建了一个
QPixmap
对象。 - 调用
load()
方法尝试加载指定路径下的图片文件。 load()
方法返回true
如果图片成功加载,否则返回false
。- 如果图片加载成功,则使用
setPixmap()
方法将其设置到QLabel
上。 - 如果图片加载失败,则
QLabel
显示一条错误消息。
想处理加载失败的情况,可以在 else
块中添加适当的代码来通知用户或记录错误。
4.上述代码中只有QLabel和QPixmap,若结合QImage来显示图片
4.1.运行
4.2.main.cpp
#include <QApplication>
#include <QLabel>
#include <QPixmap>
#include <QImage>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
QImage image;
// 尝试加载图片,替换为图片文件路径
bool loaded = image.load("/path/to/image.jpg");
if (loaded) {
// 如果图片加载成功,转换为QPixmap并设置到QLabel
QPixmap pixmap = QPixmap::fromImage(image);
label.setPixmap(pixmap);
} else {
// 如果加载失败,可以设置一个错误消息
label.setText("图片加载失败!");
}
label.show();
return app.exec();
}
4.3.附加解释
QImage
是Qt中另一个处理图像的类。与 QPixmap
相比,QImage
更适合图像的离屏处理,例如图像的像素级操作。而 QPixmap
更适合屏幕显示和绘制。
如果想在上述例子中使用 QImage
,可以首先加载图像到一个 QImage
对象中,然后将其转换为 QPixmap
来为 QLabel
设置。
在这段代码中:
- 创建了一个
QImage
对象。 - 使用
load()
方法加载图片文件到QImage
对象中。 - 如果图片成功加载,使用静态方法
QPixmap::fromImage()
将QImage
转换为QPixmap
。 - 然后使用
setPixmap()
方法将QPixmap
设置到QLabel
上。 - 如果图片加载失败,则
QLabel
显示错误消息。
这种方法允许在将图像显示在 QLabel
之前,利用 QImage
提供的功能对图像进行处理。例如,可以修改图像的大小,应用滤镜,调整颜色等。记住,所有这些操作都应该在将 QImage
转换为 QPixmap
之前完成。
4.4.代码流程图
+----------------+ +-----------------------+ +----------------+ +-----------------+ +-----------------------+ +------------------+
| Start | | 创建 QApplication | | 创建 QLabel | | 创建 QImage | | 加载图片到 QImage | | 加载成功? |
+----------------+ +-----------------------+ +----------------+ +-----------------+ +-----------------------+ +--------+---------+
| | | | | Yes / No
| | | | | / \
v v v v v / \
+----------------+ +-----------------------+ +----------------+ +-----------------+ +-----------------------+ +-------v-------+ +-----------------+
| 创建 QApplication | ---> | 创建 QLabel | ---> | 创建 QImage | ---> | 加载图片到 QImage | ---> | image.load(...) | ---> | 从 QImage | | 设置 QLabel 文本 |
+----------------+ +-----------------------+ +----------------+ +-----------------+ +-----------------------+ | 创建 QPixmap | | "图片加载失败!" |
| | | | | +-----------------+
| | | | | /
v v v v v /
+----------------+ +-----------------------+ +----------------+ +-----------------+ +-----------------------+ /
| 显示 QLabel | <--- | 设置 QLabel 的 | <--- | 设置 QLabel 的 | <--- | 加载图片到 QLabel | <------------------------+ /
+----------------+ | QPixmap | | QPixmap | | image.load(...) | /
| +-----------------------+ +----------------+ +-----------------------+ /
| /
v /
+----------------+ /
| 进入事件循环 | /
| app.exec() | /
+----------------+ /
| /
v /
+----------------+ /
| End | /
+----------------+-------------------------------------------------------------------------------------------------------------------------+
图片版
4.5.QImage
和QPixmap
表格对比
在Qt框架中,QImage
和 QPixmap
都用于处理图像,但它们各自有不同的优化点和用途。
特性 / 用途 | QImage | QPixmap |
---|---|---|
基本描述 | 用于图像的处理和转换;更像是图像数据的容器。 | 用于在屏幕上显示图像;优化了绘制速度。 |
颜色深度 | 支持多种颜色格式和颜色深度。 | 通常与显示系统的颜色深度匹配。 |
性能 | 对图像进行操作(如旋转、缩放)时性能较低。 | 绘制到屏幕上时性能较高,因为它是为显示优化的。 |
硬件加速 | 通常不使用硬件加速。 | 使用硬件加速绘制到屏幕,因此在显示时更快。 |
图像处理 | 提供像素级访问,适用于图像的处理和分析。 | 不方便直接操作像素。 |
文件交互 | 读取和写入图像文件时常用,可以直接从文件加载和保存。 | 一般不直接用于读写文件,通常通过QImage加载后转换为QPixmap进行显示。 |
内存使用 | 可以更高效地使用内存,特别是使用非本机格式时。 | 内存使用可能更高,因为它存储的是屏幕格式的数据。 |
透明度处理 | 支持alpha通道,可以处理图像的透明度。 | 同样支持alpha通道。 |
网络传输 | 用于网络传输或图像处理时更加合适,因为它能够以不同的格式存储和处理图像数据。 | 通常不用于网络传输。 |
线程安全 | 可以在非GUI线程中创建和修改。 | 必须在GUI线程中创建,因为它涉及到与显示硬件的交互。 |
使用场景示例 | - 创建图像编辑应用时 - 对图像进行分析处理 - 在后台线程处理图像 | - 在窗口或者控件中快速显示图像 - 当图像不需要在多个颜色空间中变换时使用 |
在实际开发中,选择 QImage
还是 QPixmap
取决于具体需求。如果需要处理图像数据(如过滤、变换等),QImage
是更好的选择。如果主要需求是在Qt的窗口系统中快速显示图像,QPixmap
是更合适的。有时可能需要在两者之间转换,例如,可能会从文件中加载一个图像到 QImage
中进行处理,然后将其转换为 QPixmap
以快速显示在屏幕上。
5.视频流解码的图像数据需要使用的函数:QPixmap::fromImage()
如果正在处理视频流,并且有解码后的图像数据,通常会得到一个 QImage
或者一个原始的图像数据缓冲区。如果经有了一个 QImage
实例,可以使用 QPixmap::fromImage()
方法来将其转换为 QPixmap
,从而能够在 QLabel
上显示它。
当从视频流中解码图像时,可能直接得到原始的帧数据,比如一个字节数组。在这种情况下,可以先创建一个 QImage
对象,然后使用该对象的构造函数或者 loadFromData
方法来从原始数据创建图像。一旦有了一个 QImage
对象,就可以像之前一样将其转换为 QPixmap
并将其显示在 QLabel
上。
以下是一个简化的例子,说明如何从视频流中的原始数据创建 QImage
并将其转换为 QPixmap
:
#include <QApplication>
#include <QLabel>
#include <QImage>
#include <QPixmap>
// 假设这是从视频解码得到的原始图像数据
const uchar *videoFrameData = ...; // 视频帧的原始数据指针
int videoFrameWidth = ...; // 视频帧的宽度
int videoFrameHeight = ...; // 视频帧的高度
QImage::Format format = ...; // 视频帧数据的格式
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label;
// 从原始数据创建QImage
QImage image(videoFrameData, videoFrameWidth, videoFrameHeight, format);
// 将QImage转换为QPixmap
QPixmap pixmap = QPixmap::fromImage(image);
// 设置QLabel以显示QPixmap
label.setPixmap(pixmap);
label.show();
return app.exec();
}
在这段代码中:
videoFrameData
是一个指向视频帧原始数据的指针。videoFrameWidth
和videoFrameHeight
分别是视频帧的宽度和高度。format
是一个QImage::Format
枚举值,指定了原始数据的格式。
QImage
的构造函数接受这些参数来创建图像对象。然后,可以使用 QPixmap::fromImage()
方法将 QImage
转换为 QPixmap
,接着将其设置到 QLabel
上以供显示。
请注意,确保原始数据在 QImage
存在的整个生命周期内都是有效的,除非在创建 QImage
时使用了深拷贝。此外,确保数据的格式与 QImage
支持的格式相匹配。如果格式不匹配,图像可能无法正确显示。
6.Qt在加载的图片上的指定位置画矩形框:创建一个 QPainter 实例并在 QPixmap 上绘制矩形
6.1.运行
6.2.main.cpp
#include <QApplication>
#include <QLabel>
#include <QPixmap>
#include <QPainter>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 加载图片
QPixmap pixmap("123.jpg"); // 替换为你的图片文件路径
// 创建 QPainter 绘制在 QPixmap 上
QPainter painter(&pixmap);
painter.setPen(QPen(Qt::red, 3)); // 设置画笔为红色,线宽为3
painter.drawRect(30, 40, 100, 100); // 在(10,10)位置绘制一个100x100的矩形框
painter.end(); // 结束绘画
// 将绘制好的 QPixmap 设置给 QLabel
QLabel label;
label.setPixmap(pixmap);
label.show();
return app.exec();
}
7.setScaledContents
和scaled
方法表格对比
在Qt框架中,setScaledContents
是 QWidget
的一个属性,通常用于 QLabel
或其他控件中,以指定是否应该缩放控件的内容以填充控件的大小。而 scaled
方法是 QPixmap
和 QImage
类中的一个函数,用于创建原始图像的缩放版本。
特性 / 用途 | setScaledContents | scaled 方法 |
---|---|---|
所属类 | QWidget | QPixmap / QImage |
类型 | 属性/函数 | 函数 |
功能 | 决定是否自动缩放控件内容以适应控件的大小。 | 返回图像的缩放副本。 |
用法 | 控件使用 setScaledContents(true) 来开启内容缩放。 | 调用 scaled 方法并传入新的尺寸,可选地指定缩放模式和质量。 |
缩放时机 | 控件大小变化时自动缩放内容。 | 当你调用方法时手动创建一个缩放后的图像副本。 |
返回值 | 无返回值,是一个设置属性的过程。 | 返回缩放后的 QPixmap 或 QImage 副本。 |
性能 | 对于频灁变化大小的控件可能会影响性能,因为每次大小改变都会触发重新缩放。 | 缩放操作可能会消耗时间,特别是对于大图像和高质量缩放。 |
质量控制 | 通常没有直接的质量控制选项,依赖于控件的实现。 | 可以指定缩放模式,例如 Qt::SmoothTransformation 提高缩放质量。 |
适用场景 | - 当你希望 QLabel 或其他控件自动管理内容的缩放。 - 简单的UI元素缩放。 | - 当你需要对图像进行一次性的缩放处理。 - 复杂的图像处理。 |
实现方式 | 通过设置控件的属性来实现。 | 通过调用方法并传递参数来实现。 |
内存管理 | 不会创建新的图像副本,但频繁更新可能导致性能问题。 | 创建一个新的图像副本,可能会增加程序的内存使用。 |
线程安全性 | 属性设置通常需要在GUI线程中完成。 | QImage 的 scaled 方法可以在非GUI线程中使用。 |
可扩展性 | 适用于任何 QWidget 派生的控件,但不提供缩放逻辑的自定义。 | 允许通过不同的参数来微调缩放的结果,更灵活。 |
例子 | myLabel->setScaledContents(true); | QPixmap scaledPixmap = originalPixmap.scaled(newWidth, newHeight); |
总结:
setScaledContents
是一个控件属性,用于自动调整内容大小以适应控件的尺寸变化。scaled
是QPixmap
或QImage
对象的一个方法,用于生成指定大小的缩放副本,它允许更多的控制,如缩放模式和质量选择。