studia/jezyki-skryptowe/image-editor/editor/dialogs/ResizeDialog.py

131 lines
4.4 KiB
Python

import numpy as np
import cv2
from PyQt6.QtWidgets import QLabel, QVBoxLayout, QHBoxLayout, QLineEdit, QCheckBox, QComboBox
from PyQt6.QtGui import QIntValidator
import ImageProcessingWorker
from .ImageParameterDialog import ImageParameterDialog
INTERPOLATION_MAP = {
"Nearest": cv2.INTER_NEAREST,
"Linear": cv2.INTER_LINEAR,
"Area": cv2.INTER_AREA,
"Cubic": cv2.INTER_CUBIC,
"Lanczos4": cv2.INTER_LANCZOS4
}
class ResizeDialog(ImageParameterDialog):
def __init__(self, image):
super().__init__(image, ImageProcessingWorker.ImageProcessingWorker)
self.original_height, self.original_width, _ = image.shape
self.setWindowTitle("Resizing")
self.layout = QVBoxLayout()
self.width_label = QLabel("Width:")
self.width_field = QLineEdit()
self.width_field.setPlaceholderText("Enter width")
self.width_field.setText(str(self.original_width))
self.width_field.setValidator(QIntValidator(1, 10000))
self.width_field.textEdited.connect(self.width_changed)
self.height_label = QLabel("Height:")
self.height_field = QLineEdit()
self.height_field.setPlaceholderText("Enter height")
self.height_field.setText(str(self.original_height))
self.height_field.setValidator(QIntValidator(1, 10000))
self.height_field.textEdited.connect(self.height_changed)
self.auto_scale_checkbox = QCheckBox("Auto-scale")
self.auto_scale_checkbox.setChecked(True)
self.auto_scale_checkbox.stateChanged.connect(self.toggle_auto_scale)
self.interpolation_label = QLabel("Interpolation Method:")
self.interpolation_dropdown = QComboBox()
self.interpolation_dropdown.addItems(list(INTERPOLATION_MAP.keys()))
self.interpolation_dropdown.currentIndexChanged.connect(self.update)
input_layout = QHBoxLayout()
input_layout.addWidget(self.width_label)
input_layout.addWidget(self.width_field)
input_layout.addWidget(self.height_label)
input_layout.addWidget(self.height_field)
self.layout.addLayout(input_layout)
self.layout.addWidget(self.auto_scale_checkbox)
self.layout.addWidget(self.interpolation_label)
self.layout.addWidget(self.interpolation_dropdown)
self.layout.addWidget(self.button_box)
self.setLayout(self.layout)
self.toggle_auto_scale()
def toggle_auto_scale(self):
if self.auto_scale_checkbox.isChecked():
self.adjust_height()
self.update()
def adjust_height(self):
if self.auto_scale_checkbox.isChecked():
try:
width = int(self.width_field.text())
height = int((width / self.original_width) * self.original_height)
self.height_field.setText(str(height))
except ValueError:
self.height_field.clear()
def adjust_width(self):
if self.auto_scale_checkbox.isChecked():
try:
height = int(self.height_field.text())
width = int((height / self.original_height) * self.original_width)
self.width_field.setText(str(width))
except ValueError:
self.width_field.clear()
def height_changed(self):
self.adjust_width()
self.update()
def width_changed(self):
self.adjust_height()
self.update()
def update(self):
width = self.width_field.text()
height = self.height_field.text()
if (not width or not height):
self.set_accept_enable(False)
return
self.send_to_process({
'width': int(width),
'height': int(height),
'auto_scale': self.auto_scale_checkbox.isChecked(),
'interpolation': self.interpolation_dropdown.currentText()
})
def process_image(self, image, values):
if values['width'] == 0 or values['height'] == 0:
return image
interpolation = INTERPOLATION_MAP[values['interpolation']]
try:
resized_image = cv2.resize(image, (values['width'], values['height']), interpolation=interpolation)
except:
self.set_accept_enable(False)
return image
self.set_accept_enable(True)
return resized_image
@classmethod
def dialog_name(cls):
return "Resize"