继上一篇博文《Python 学习之简易图片浏览器》,我们实现了本地图片浏览功能。今天再接再厉,在此基础上实现放大/缩小、顺/逆时针旋转、垂直/水平翻转、图片拖动这几个功能。
先上效果图
效果图show完,开始贴这几个功能的核心代码。
由于之前用了setFixSize固定了QLabel的尺寸,接下来的操作需要先恢复:
self.label.setMinimumSize(0, 0)
self.label.setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))
放大/缩小功能
先设一个放大缩小因子self.scaleFactor = 1.0,然后再输入放大/缩小倍数factor,如每次都按照25%来放大/缩小,放大factor=1.25,缩小factor=0.8。然后就可以直接用QLabel的resize()实现放大缩小功能。
self.scaleFactor *= factor
self.label.resize(self.scaleFactor * self.label.pixmap().size())
顺/逆时针90度旋转
这里用到了Qtransform()模块中的rotate()函数,在rotate()里填写你要旋转的度数,顺时针是正数,逆时针是负数。
transform = QTransform()
transform.rotate(-90)
self.img = self.img.transformed(transform)
self.label.resize(self.img.width(), self.img.height())
self.label.setPixmap(self.img)
- 垂直/水平翻转
垂直翻转其实用transform.rotate(180)也能实现。不过,我这里使用的opencv的flip()函数,flip(img,0)是垂直翻转,flip(img,1)是水平翻转。需要提一句,这里要用到将Qpixmap和CV图像互转。
img1 = qtpixmap_to_cvimg(self.img)
img1 = cv2.flip(img1, 1)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
img3 = QtGui.QImage(img2[:], img2.shape[1], img2.shape[0], img2.shape[1] * 3, QtGui.QImage.Format_RGB888)
self.img = QtGui.QPixmap(img3).scaled(self.label_w, self.label_h)
self.label.resize(self.img.width(), self.img.height())
self.label.setPixmap(self.img)
qpixmap转cvimg的函数:
def qtpixmap_to_cvimg(qtpixmap):
# qpixmap转成cv图片
qimg = qtpixmap.toImage()
temp_shape = (qimg.height(), qimg.bytesPerLine() * 8 // qimg.depth())
temp_shape += (4,)
ptr = qimg.bits()
ptr.setsize(qimg.byteCount())
result = np.array(ptr, dtype=np.uint8).reshape(temp_shape)
result = result[..., :3]
return result
拖动图像
拖动图像用到的是鼠标事件,分别是mousePressEvent、mouseReleaseEvent和mouseMoveEvent,在前两个事件主要是设置一个self.flag的bool值,点击为True,松开WieFalse。然后就是鼠标拖动,并且在拖动的时候通过setGeometry()函数重新规划QLabel方位。
def myMousePressEvent(self, source, e):
# 鼠标点击事件
if e.buttons() == QtCore.Qt.LeftButton:
self.flag = True
def myMouseReleaseEvent(self, source, e):
# 鼠标释放事件
self.flag = False
self.movex = ""
self.movey = ""
def myMouseMoveEvent(self, source, e):
# 图像随鼠标移动
if self.flag:
self.x1 = e.x()
self.y1 = e.y()
if self.movex != "" and self.movey != "":
self.label_x = self.label_x + (self.x1 - self.movex)
self.label_y = self.label_y + (self.y1 - self.movey)
self.movex = self.x1
self.movey = self.y1
self.label.setGeometry(QtCore.QRect(self.label_x, self.label_y, self.label_w, self.label_h))
基于上述核心代码,你可以通过添加鼠标事件,添加menu菜单,添加button来触发这些功能,同时还可以进一步扩展,大家自己探索尝试吧^_^