You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
3.0 KiB
88 lines
3.0 KiB
2 years ago
|
import cv2
|
||
|
|
||
|
from PyQt5.QtGui import *
|
||
|
from PyQt5.QtCore import *
|
||
|
from PyQt5.QtWidgets import *
|
||
|
|
||
|
|
||
|
class GraphicsView(QGraphicsView):
|
||
|
def __init__(self, parent=None):
|
||
|
super(GraphicsView, self).__init__(parent=parent)
|
||
|
self._zoom = 0
|
||
|
self._empty = True
|
||
|
self._photo = QGraphicsPixmapItem() # 创建pixmapItem对象用于显示图像
|
||
|
self._scene = QGraphicsScene(self) # 创建存储图元的容器
|
||
|
self._scene.addItem(self._photo)
|
||
|
self.setScene(self._scene)
|
||
|
self.setAlignment(Qt.AlignCenter) # 居中显示
|
||
|
self.setDragMode(QGraphicsView.ScrollHandDrag) # 设置拖动
|
||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||
|
self.setMinimumSize(640, 480)
|
||
|
|
||
|
def contextMenuEvent(self, event):
|
||
|
if not self.has_photo():
|
||
|
return
|
||
|
menu = QMenu()
|
||
|
save_action = QAction('另存为', self)
|
||
|
save_action.triggered.connect(self.save_current) # 传递额外值
|
||
|
menu.addAction(save_action)
|
||
|
menu.exec(QCursor.pos())
|
||
|
|
||
|
def save_current(self):
|
||
|
file_name = QFileDialog.getSaveFileName(self, '另存为', './',
|
||
|
'Image files(*.jpg *.gif *.png)')[0]
|
||
|
print(file_name)
|
||
|
if file_name:
|
||
|
self._photo.pixmap().save(file_name)
|
||
|
|
||
|
def get_image(self):
|
||
|
if self.has_photo():
|
||
|
return self._photo.pixmap().toImage() # 获取
|
||
|
|
||
|
def has_photo(self):
|
||
|
return not self._empty
|
||
|
|
||
|
def img_to_pixmap(self, img):
|
||
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # bgr -> rgb
|
||
|
h, w, c = img.shape # 获取图片形状
|
||
|
image = QImage(img, w, h, 3 * w, QImage.Format_RGB888)
|
||
|
return QPixmap.fromImage(image)
|
||
|
|
||
|
def update_image(self, img):
|
||
|
self._empty = False
|
||
|
self._photo.setPixmap(self.img_to_pixmap(img))
|
||
|
|
||
|
def change_image(self, img):
|
||
|
self.update_image(img)
|
||
|
self.fitInView()
|
||
|
|
||
|
def fitInView(self, scale=True):
|
||
|
rect = QRectF(self._photo.pixmap().rect())
|
||
|
if not rect.isNull():
|
||
|
self.setSceneRect(rect)
|
||
|
if self.has_photo():
|
||
|
unity = self.transform().mapRect(QRectF(0, 0, 1, 1))
|
||
|
self.scale(1 / unity.width(), 1 / unity.height())
|
||
|
viewrect = self.viewport().rect()
|
||
|
scenerect = self.transform().mapRect(rect)
|
||
|
factor = min(viewrect.width() / scenerect.width(),
|
||
|
viewrect.height() / scenerect.height())
|
||
|
self.scale(factor, factor)
|
||
|
self._zoom = 0
|
||
|
|
||
|
def wheelEvent(self, event):
|
||
|
if self.has_photo():
|
||
|
if event.angleDelta().y() > 0:
|
||
|
factor = 1.25
|
||
|
self._zoom += 1
|
||
|
else:
|
||
|
factor = 0.8
|
||
|
self._zoom -= 1
|
||
|
if self._zoom > 0:
|
||
|
self.scale(factor, factor)
|
||
|
elif self._zoom == 0:
|
||
|
self.fitInView()
|
||
|
else:
|
||
|
self._zoom = 0
|