studia/jezyki-skryptowe/image-editor/dialogs/ResizeDialog.py
2024-06-17 23:55:32 +02:00

137 lines
4.7 KiB
Python

import ImageProcessingWorker
import numpy as np
import cv2
from PyQt6.QtWidgets import (QApplication, QLabel, QVBoxLayout, QHBoxLayout, QPushButton, QWidget, QFileDialog, QSlider,
QLineEdit, QDialog, QCheckBox, QComboBox)
from PyQt6.QtGui import QPixmap, QImage, QColor, QPainter, QPen, QIntValidator
from PyQt6.QtCore import Qt, QPoint, QThread
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()
# Width input
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)
# Height input
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)
# Auto-scaling checkbox
self.auto_scale_checkbox = QCheckBox("Auto-scale")
self.auto_scale_checkbox.setChecked(True)
self.auto_scale_checkbox.stateChanged.connect(self.toggle_auto_scale)
# Interpolation method dropdown
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)
# Layout for input fields
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() # Initially disable the width and height fields
def toggle_auto_scale(self):
if self.auto_scale_checkbox.isChecked():
self.adjust_height()
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"