image management
This commit is contained in:
parent
44f4a9a4bc
commit
296d1ef7d4
|
|
@ -4,7 +4,7 @@ from PyQt6.QtCore import Qt
|
||||||
|
|
||||||
class ImageCanvas(QGraphicsView):
|
class ImageCanvas(QGraphicsView):
|
||||||
_pixmapItem: QGraphicsPixmapItem
|
_pixmapItem: QGraphicsPixmapItem
|
||||||
|
empty = True
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
@ -30,6 +30,16 @@ class ImageCanvas(QGraphicsView):
|
||||||
def updatePixmap(self, image: QImage):
|
def updatePixmap(self, image: QImage):
|
||||||
pixmap = QPixmap.fromImage(image)
|
pixmap = QPixmap.fromImage(image)
|
||||||
self._pixmapItem.setPixmap(pixmap)
|
self._pixmapItem.setPixmap(pixmap)
|
||||||
|
if self.empty:
|
||||||
|
self.reset()
|
||||||
|
self.empty = False
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.scene.removeItem(self._pixmapItem)
|
||||||
|
self._pixmapItem = QGraphicsPixmapItem()
|
||||||
|
self.scene.addItem(self._pixmapItem)
|
||||||
|
|
||||||
|
self.empty = True
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.resetTransform() # Reset the zoom level to default
|
self.resetTransform() # Reset the zoom level to default
|
||||||
|
|
|
||||||
73
jezyki-skryptowe/image-editor/ImageManagePanel.py
Normal file
73
jezyki-skryptowe/image-editor/ImageManagePanel.py
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
from PyQt6.QtWidgets import QFileDialog, QWidget, QToolBar, QHBoxLayout, QPushButton
|
||||||
|
from PyQt6.QtGui import QIcon
|
||||||
|
from PyQt6.QtCore import pyqtSignal
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from ImageManager import ImageManager
|
||||||
|
|
||||||
|
class ImageManagePanel(QWidget):
|
||||||
|
on_update = pyqtSignal(np.ndarray)
|
||||||
|
on_close = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.mgr = ImageManager(self._on_update)
|
||||||
|
|
||||||
|
layout = QHBoxLayout()
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
self.open_button = QPushButton(QIcon.fromTheme("document-open"), "Open", self)
|
||||||
|
layout.addWidget(self.open_button)
|
||||||
|
self.open_button.clicked.connect(self._open_image)
|
||||||
|
|
||||||
|
self.save_button = QPushButton(QIcon("save.png"), "Save", self)
|
||||||
|
layout.addWidget(self.save_button)
|
||||||
|
self.save_button.clicked.connect(self._save_image)
|
||||||
|
|
||||||
|
self.close_button = QPushButton(QIcon("close.png"), "Close", self)
|
||||||
|
layout.addWidget(self.close_button)
|
||||||
|
self.close_button.clicked.connect(self._close_image)
|
||||||
|
|
||||||
|
self.undo_button = QPushButton(QIcon("undo.png"), "Undo", self)
|
||||||
|
layout.addWidget(self.undo_button)
|
||||||
|
self.undo_button.clicked.connect(self._undo)
|
||||||
|
|
||||||
|
self.redo_button = QPushButton(QIcon("redo.png"), "Redo", self)
|
||||||
|
layout.addWidget(self.redo_button)
|
||||||
|
self.redo_button.clicked.connect(self._redo)
|
||||||
|
|
||||||
|
self._enable_buttons()
|
||||||
|
|
||||||
|
def _redo(self):
|
||||||
|
self.mgr.redo()
|
||||||
|
self._enable_buttons()
|
||||||
|
|
||||||
|
def _undo(self):
|
||||||
|
self.mgr.undo()
|
||||||
|
self._enable_buttons()
|
||||||
|
|
||||||
|
def _on_update(self, image):
|
||||||
|
self.on_update.emit(image)
|
||||||
|
self._enable_buttons()
|
||||||
|
|
||||||
|
def _enable_buttons(self):
|
||||||
|
self.undo_button.setEnabled(self.mgr.can_undo())
|
||||||
|
self.redo_button.setEnabled(self.mgr.can_redo())
|
||||||
|
|
||||||
|
|
||||||
|
def _close_image(self):
|
||||||
|
self.mgr.close()
|
||||||
|
self.on_close.emit()
|
||||||
|
|
||||||
|
def _open_image(self):
|
||||||
|
file_name, _ = QFileDialog.getOpenFileName(self, "Open Image File", "", "Image Files (*.jpg *.jpeg *.png)")
|
||||||
|
if file_name:
|
||||||
|
self.mgr.open(file_name)
|
||||||
|
|
||||||
|
def _save_image(self):
|
||||||
|
file_name, _ = QFileDialog.getSaveFileName(self, "Save Image File", "", "Image Files (*.jpg *.png)")
|
||||||
|
if file_name:
|
||||||
|
self.mgr.save(file_name)
|
||||||
|
|
||||||
|
|
||||||
61
jezyki-skryptowe/image-editor/ImageManager.py
Normal file
61
jezyki-skryptowe/image-editor/ImageManager.py
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import cv2
|
||||||
|
|
||||||
|
class ImageManager():
|
||||||
|
|
||||||
|
def __init__(self, update_fn):
|
||||||
|
super().__init__()
|
||||||
|
self.update_fn = update_fn
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def undo(self):
|
||||||
|
if len(self._undo_deque) == 0:
|
||||||
|
return
|
||||||
|
prev = self._undo_deque.pop()
|
||||||
|
self._redo_deque.append(self._curr_image)
|
||||||
|
self._curr_image = prev
|
||||||
|
self.update_fn(self._curr_image)
|
||||||
|
|
||||||
|
def redo(self):
|
||||||
|
if len(self._redo_deque) == 0:
|
||||||
|
return
|
||||||
|
latter = self._redo_deque.pop()
|
||||||
|
self._undo_deque.append(self._curr_image)
|
||||||
|
self._curr_image = latter
|
||||||
|
self.update_fn(self._curr_image)
|
||||||
|
|
||||||
|
def update(self, new_image):
|
||||||
|
self._undo_deque.append(self._curr_image)
|
||||||
|
self._redo_deque = deque()
|
||||||
|
self._curr_image = new_image.copy()
|
||||||
|
self.update_fn(self._curr_image)
|
||||||
|
|
||||||
|
def open(self, file_name):
|
||||||
|
self.close()
|
||||||
|
self._curr_image = cv2.imread(file_name)
|
||||||
|
self._curr_image = cv2.cvtColor(self._curr_image, cv2.COLOR_BGR2RGB)
|
||||||
|
self.update_fn(self._curr_image)
|
||||||
|
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self._undo_deque = deque()
|
||||||
|
self._redo_deque = deque()
|
||||||
|
self._curr_image = None
|
||||||
|
|
||||||
|
def save(self, file_name):
|
||||||
|
if self._curr_image is not None:
|
||||||
|
cv2.imwrite(file_name, cv2.cvtColor(self._curr_image, cv2.COLOR_RGB2BGR))
|
||||||
|
|
||||||
|
def refresh(self):
|
||||||
|
self.update_fn(self._curr_image)
|
||||||
|
|
||||||
|
def image(self):
|
||||||
|
return self._curr_image
|
||||||
|
|
||||||
|
def can_redo(self):
|
||||||
|
return len(self._redo_deque) > 0
|
||||||
|
|
||||||
|
def can_undo(self):
|
||||||
|
return len(self._undo_deque) > 0
|
||||||
Loading…
Reference in New Issue
Block a user