〇、前言
图,貌似是一个好看的 UI 中必不可少的东西,精美的 UI 中不可避免的会使用一些奇特的各种图像元素来提升用户体验。对于开发者而言,如何在应用程序中有效地显示和处理图像成为一个重要的课题。在 Python 中,PyQt 库是一个强大而灵活的选择,它提供了丰富的图像处理类和功能。
PyQt 中的图像类和组件使开发者能够加载、保存、绘制和转换图像,从而实现各种图像操作。其中,常用的图像类包括 QPixmap、QImage 和 QIcon。QPixmap 和 QImage 提供了基本的图像处理功能,可以加载、保存、缩放、剪裁和绘制图像。QIcon 则用于在 GUI 应用程序中显示图标,可以加载图像文件并在按钮、菜单等控件上展示图标。
此外,PyQt 还提供了其他一些与图像相关的类和组件,如 QBrush、QPen 和 QPainter,它们可以帮助开发者实现更高级的图像操作,如填充样式、画笔样式以及绘制各种图形元素等。而使用 QGraphicsView 和 QGraphicsScene 组件可以实现更复杂的图形场景展示和交互,适用于绘图、图表和地图等应用领域。
通过 PyQt 提供的丰富图像类和组件,开发者可以轻松地在应用程序中展示精美的图像,提升用户界面的吸引力和可用性。无论是创建一个简单的图像展示功能,还是实现复杂的图形交互,PyQt 都为开发者提供了强大而灵活的工具。在接下来的部分,我将简单介绍一下图像类及图像相关类,方便大家在学习的时候打开文章进行参考。
一、PyQt 中的图像类
1、图像类简介
PyQt 中提供了许多用于处理图像的类和功能,来用于处理图像加载、保存、绘制和转换等操作。下面是 PyQt 中比较常用的图像类:
QPixmap:用于处理图像的基本类。它可以加载、保存、缩放、剪裁和绘制图像。
QImage:与 QPixmap 类似,也用于处理图像。它支持更多的图像格式和操作,包括像素级别的访问和修改。
QIcon:用于在 GUI 应用程序中显示图标的类。它可以加载图像文件,并在按钮、菜单等控件上显示图标。
QPicture:用于记录和重播绘图操作的类。它可以存储绘制图形的指令,然后在需要时进行重绘。
QImageReader:用于读取不同格式的图像文件的类。它可以加载各种图像文件,并将其转换为 QImage 或 QPixmap 对象。
QImageWriter:用于将图像写入不同格式的图像文件的类。它可以将 QImage 或 QPixmap 对象保存为各种图像文件。
此外,PyQt 还提供了其他一些与图像相关的类和功能,它们提供了更多高级的图形处理功能,例如绘制、渲染、填充等。它们可以帮助你在 PyQt 应用程序中更灵活地处理和展示图像和图形元素:
QBitmap:用于创建位图的类。它可以用于创建透明或非透明的图像,通常用于制作形状非矩形的控件。
QBrush:用于描述绘画操作中的填充样式的类。它可以用于填充图形元素,如矩形、椭圆、多边形等。
QPen:用于描述绘画操作中的画笔样式的类。它可以用于指定绘制图形边框的颜色、宽度、样式等。
QPainter:用于绘制图形和图像的类。它提供了各种绘制图形元素的方法,如绘制直线、矩形、椭圆、文本等。
QGraphicsView:用于显示和交互大型图形场景的类。它可以用于展示和操作复杂的图形,如绘图、图表、地图等。
QOpenGLWidget:用于在 GUI 应用程序中显示 OpenGL 渲染的图形的类。它提供了与 OpenGL 集成的功能,可以显示和交互 3D 图形。
2、图像类转换
① 常用类转换(QPixmap、QImage、QIcon)
QPixmap 转换为 QImage:
pixmap = QPixmap("image.png") # 创建一个 QPixmap 对象
image = pixmap.toImage() # 转换为 QImage 对象
复制代码
QImage 转换为 QPixmap:
image = QImage("image.png") # 创建一个 QImage 对象
pixmap = QPixmap.fromImage(image) # 转换为 QPixmap 对象
复制代码
QImage 转换为 QIcon:
image = QImage("image.png") # 创建一个 QImage 对象
icon = QIcon(QPixmap.fromImage(image)) # 转换为 QIcon 对象
复制代码
QPixmap 转换为 QIcon:
pixmap = QPixmap("image.png") # 创建一个 QPixmap 对象
icon = QIcon(pixmap) # 转换为 QIcon 对象
复制代码
这些是常见的一些类之间的转换示例。根据你的具体需求和使用情况,你可以根据需要进行适当的转换。值得注意的是,有些类之间的转换可能会引入一定的性能开销或图像数据的损失,因此在进行转换时要小心处理。
② QBitmap、QBrush、QPen 转换为 QPixmap 或 QImage
QBitmap 转换为 QPixmap 或 QImage:
bitmap = QBitmap("bitmap.png") # 创建一个 QBitmap 对象
pixmap = QPixmap.fromImage(bitmap.toImage()) # 将 QBitmap 转换为 QPixmap
image = bitmap.toImage() # 将 QBitmap 转换为 QImage
复制代码
QBrush 转换为 QPixmap:
brush = QBrush(Qt.SolidPattern) # 创建一个 QBrush 对象
pixmap = QPixmap(100, 100) # 创建一个 QPixmap 对象
pixmap.fill(brush.color()) # 使用 QBrush 的颜色填充 QPixmap
复制代码
QPen 转换为 QPixmap 或 QImage:
pen = QPen(Qt.red) # 创建一个 QPen 对象
pixmap = QPixmap(100, 100) # 创建一个 QPixmap 对象
pixmap.fill(Qt.white) # 填充 QPixmap
painter = QPainter(pixmap)
painter.setPen(pen)
painter.drawLine(0, 0, 100, 100) # 在 QPixmap 上绘制线条
painter.end()
image = pixmap.toImage() # 将 QPixmap 转换为 QImage
复制代码
这些示例展示了一些其他类之间的转换方法。根据你的具体需求,你可以选择适当的方法来转换不同的图像类。记住,在进行转换时,你需要考虑数据格式、性能和目标类的要求。
③ QByteArray 与 QPixmap、QImage 的互转
QPixmap 或 QImage 转换为 QByteArray:
pixmap = QPixmap("image.png") # 创建一个 QPixmap 对象
byte_array = QByteArray()
buffer = QBuffer(byte_array)
buffer.open(QIODevice.WriteOnly)
pixmap.save(buffer, "PNG") # 将 QPixmap 转换为 QByteArray
buffer.close()
# 或者
image = QImage("image.png") # 创建一个 QImage 对象
byte_array = QByteArray()
buffer = QBuffer(byte_array)
buffer.open(QIODevice.WriteOnly)
image.save(buffer, "PNG") # 将 QImage 转换为 QByteArray
buffer.close()
复制代码
QByteArray 转换为 QPixmap 或 QImage:
byte_array = QByteArray()
# 假设 byte_array 包含图像数据
pixmap = QPixmap()
pixmap.loadFromData(byte_array) # 将 QByteArray 转换为 QPixmap
# 或者
image = QImage()
image.loadFromData(byte_array) # 将 QByteArray 转换为 QImage
复制代码
这些示例展示了如何在 QPixmap、QImage 和 QByteArray 之间进行转换。使用适当的方法,你可以实现图像数据的存储、加载和传输。请根据你的具体需求选择适合的转换方法。
④ numpy 与 QImage 互转
QImage 转换为 numpy 数组:
image = QImage("image.png") # 创建一个 QImage 对象
width = image.width()
height = image.height()
array = np.zeros([height, width, 4], dtype=np.uint8) # 创建一个空的 numpy 数组
for y in range(height):
for x in range(width):
pixel = image.pixel(x, y) # 获取像素值
rgba = QColor(pixel).getRgb() # 转换为 RGBA 值
array[y, x] = rgba # 将 RGBA 值存入 numpy 数组
复制代码
numpy 数组转换为 QImage:
array = np.zeros([100, 100, 4], dtype=np.uint8) # 创建一个 numpy 数组
array[:, :, 0] = 255 # 将红色通道设置为 255
image = QImage(array.data, 100, 100, QImage.Format_RGBA8888) # 将 numpy 数组转换为 QImage
复制代码
这些示例展示了如何在 QImage 和 numpy 数组之间进行转换。转换为 numpy 后,可以更方便的进行深度学习。
二、图像显示组件
想要将图像显示出来,仅有上面这些图像类可不行,还需要一些组件将图像给显示出来。常用的组件有 QLabel 与 QGraphiceView,这里将着重介绍这两个图像显示组件,并对其他的一些图像显示组件进行简单介绍。根据自己不同的需求以及场景,大家可以选择不同的组件来显示图像。
下面是一张分辨率超高的图,后面对图像显示的实验中,都将使用这张图片进行操作,大家可以比对这两张图,来感受不同组件之间的差异。(图片分辨率 3637×2433,来自于 Pexels Ánh Đặng 图片: https://www.pexels.com/zh-cn/photo/16392177/)
1、使用 QLabel 显示图像
QLabel 在我目前的认知中算是一个比较常见的组件,可以用来进行图像以及文字的显示,下面是一段使用 QLabel 显示图像的简单示例程序
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
from PyQt5.QtGui import QPixmap
app = QApplication([])
window = QWidget()
# 创建QLabel组件
label = QLabel(window)
# 加载图像文件
pixmap = QPixmap("image.jpg")
# 设置图像为QLabel的内容
label.setPixmap(pixmap)
# 显示窗口
window.show()
app.exec_()
复制代码
在上述代码中,我们创建了一个 QLabel 组件并将其添加到窗口中。然后,使用 QPixmap 加载图像文件,并使用 setPixmap()方法将图像设置为 QLabel 的内容。最后,我们显示窗口并进入应用程序的事件循环。
然而,QLabel 在显示图片时并不完美,下图是上述代码使用 QLabel 对一张上述比我屏幕还要大的图片进行显示的结果,可以看到 QLabel 在不进行任何操作的情况下,并不能将我的图片完全显示,只是显示了图片左上角的一部分。
下面是我使用 pixmap 的 scaled 方法对图像进行缩放后的代码以及图像,大家可以重新感觉一下:
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
from PyQt5.QtGui import QPixmap, QTransform
app = QApplication([])
window = QWidget()
# 创建QLabel组件
label = QLabel(window)
# 设置QLabel大小
label.setFixedSize(600, 400)
# 加载图像文件
pixmap = QPixmap("image.jpg")
# 调整图像大小
scaled_pixmap = pixmap.scaled(600, 400, aspectRatioMode=Qt.KeepAspectRatio)
# 设置图像为QLabel的内容
label.setPixmap(scaled_pixmap)
# 显示窗口
window.show()
app.exec_()
复制代码
2、使用 QGraphicsView 展示图像和图形场景
QGraphicsView 是一个用于展示图像和图形场景的强大组件。它提供了对图像的缩放、平移和交互操作的支持。
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
app = QApplication([])
view = QGraphicsView()
scene = QGraphicsScene()
# 加载图像文件
pixmap = QPixmap("image.jpg")
# 在场景中添加图像
scene.addPixmap(pixmap)
# 设置场景为QGraphicsView的场景
view.setScene(scene)
# 设置图像居中显示
view.setAlignment(Qt.AlignCenter)
# 显示QGraphicsView组件
view.show()
app.exec_()
复制代码
在上述代码中,我们创建了一个 QGraphicsView 组件和一个 QGraphicsScene 场景。使用 QPixmap 加载图像文件,然后将图像添加到场景中。接着,将场景设置为 QGraphicsView 的场景,并使用 setAlignment()方法使图像居中显示。最后,显示 QGraphicsView 组件并进入应用程序的事件循环。
下面是图像显示的后果,可以看到,QGraphicsView 与 QLabel 在显示图像时还是有一些区别的,我们从图中能看到的就比如 QGraphics 有一个滚动条,而 QLabel 没有;这主要是因为 QGraphicsView 提供了更高级的图形操作和交互功能,而 QLabel 更适合显示静态图像。
3、其他可用的图像显示组件和控件
常用的用来显示图像的方法主要就是 QLabel 与 QGraphicsView 组件,这两个组件已经能够满足大多数应用场景的需求,其他的一些也可以用来显示图像的组件或方法下面也就简单介绍一下,有特殊需求的小伙伴可以看一下:
① 使用 QPainter 绘制图像:
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QImage, QPainter
app = QApplication([])
window = QWidget()
image = QImage("image.jpg") # 通过文件路径加载图像
image = image.scaled(600, 400, aspectRatioMode=Qt.KeepAspectRatio) # 调整图像大小
def paintEvent(event):
painter = QPainter(window)
painter.drawImage(0, 0, image) # 在指定位置绘制图像
window.paintEvent = paintEvent
window.show()
app.exec_()
复制代码
② 使用 QSS 加载图片为窗口的背景:
from PyQt5.QtWidgets import QApplication, QWidget
app = QApplication([])
window = QWidget()
window.setStyleSheet( #QSS 加载图片
"QWidget{border-image:url(image.jpg)}"
)
window.show()
app.exec_()
复制代码
③ 使用 QGraphicsPixmapItem 显示图像
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QGraphicsPixmapItem
app = QApplication([])
view = QGraphicsView()
scene = QGraphicsScene()
pixmap = QPixmap("image.jpg") # 通过文件路径加载图像
item = QGraphicsPixmapItem(pixmap)
scene.addItem(item)
view.setScene(scene)
view.setAlignment(Qt.AlignCenter)
view.show()
app.exec_()
复制代码
三、图像操作与转换
下面是一些使用 PyQt 方法图像进行操作和转换的简单实例,包括缩放、剪裁、旋转、调整亮度和对比度等。需要的可以参考使用。
1、缩放图像
缩放图像是调整图像尺寸的常见操作之一。PyQt 提供了 scaled()
方法来实现图像的缩放。下面是一段实例代码:
from PyQt5.QtGui import QPixmap
# 加载图像文件
pixmap = QPixmap("image.jpg")
# 缩放图像
scaled_pixmap = pixmap.scaled(800, 600)
复制代码
2、剪裁图像
剪裁图像是根据指定的区域截取图像的操作。在 PyQt 中,你可以使用 copy()
方法来实现图像的剪裁。下面是一段示例代码:
from PyQt5.QtGui import QPixmap
# 加载图像文件
pixmap = QPixmap("image.jpg")
# 定义剪裁区域
x = 100
y = 100
width = 200
height = 200
# 剪裁图像
cropped_pixmap = pixmap.copy(x, y, width, height)
复制代码
3、旋转图像
旋转图像是将图像按指定角度进行旋转的操作。PyQt 提供了 transformed()
方法来实现图像的旋转。
from PyQt5.QtGui import QPixmap, QTransform
# 加载图像文件
pixmap = QPixmap("image.jpg")
# 定义旋转角度
angle = 45
# 旋转图像
transform = QTransform().rotate(angle)
rotated_pixmap = pixmap.transformed(transform)
复制代码
4、调整亮度和对比度
调整图像的亮度和对比度可以改变图像的整体明暗和对比度水平。PyQt 中可以通过遍历每一个像素来调整像素值实现这些操作。
from PyQt5.QtGui import QImage
# 加载图像文件
image = QImage("image.jpg")
# 调整亮度和对比度
brightness = 60 # 亮度调整值,可以是正数或负数
contrast = 1.2 # 对比度调整值,可以是大于1的浮点数或小于1的浮点数
# 获取图像的尺寸
width = image.width()
height = image.height()
# 调整亮度和对比度
for y in range(height):
for x in range(width):
pixel = image.pixel(x, y)
# 获取像素的RGB值
r, g, b, a = qRed(pixel), qGreen(pixel), qBlue(pixel), qAlpha(pixel)
# 调整亮度
r += brightness
g += brightness
b += brightness
# 调整对比度
r = int((r - 128) * contrast + 128)
g = int((g - 128) * contrast + 128)
b = int((b - 128) * contrast + 128)
# 限制RGB值在0-255范围内
r = max(0, min(r, 255))
g = max(0, min(g, 255))
b = max(0, min(b, 255))
# 更新像素值
pixel = qRgba(r, g, b, a)
image.setPixel(x, y, pixel)
复制代码
5、图像滤镜
图像滤镜是一种通过改变像素的颜色或亮度来改变图像外观的技术。PyQt 中可以使用QGraphicsEffect
类和其子类来实现图像滤镜效果。下面是一段简单的代码示例:
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsBlurEffect
from PyQt5.QtGui import QPixmap
# 创建场景和视图
scene = QGraphicsScene()
# 加载图像文件
pixmap = QPixmap("image.jpg")
# 创建图像项并添加到场景
item = scene.addPixmap(pixmap)
# 创建图像模糊滤镜
effect_blur = QGraphicsBlurEffect()
effect_blur.setBlurRadius(5) # 设置模糊半径
item.setGraphicsEffect(effect_blur)
# 应用滤镜效果到图像项
item.setGraphicsEffect(effect_blur)
复制代码
6、转换图像格式
有时候,你可能需要将图像从一种格式转换为另一种格式。PyQt 提供了convertToFormat()
方法来实现图像格式的转换。
from PyQt5.QtGui import QImage, QPixmap
# 加载图像文件
image = QImage("image.jpg")
# 将图像转换为另一种格式
new_format = QImage.Format_RGB888
new_image = image.convertToFormat(new_format)
# 将QImage转换为QPixmap
pixmap = QPixmap.fromImage(new_image)
复制代码
⭐写在最后
如果你感到本文对你有帮助,那就点个赞呗👍!
评论