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.

193 lines
6.6 KiB

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import *
import PyQt6.QtGui as QtGui
from PyQt6.QtGui import QColor, QAction, QPixmap, QPalette
from pathlib import Path
import cv2
import numpy as np
from Photo import Photo
from functools import partial
class Judge:
def __init__(self, newWindow: QDialog, confirm, cancel):
button1 = QPushButton('Confirm', newWindow)
button1.clicked.connect(confirm)
button2 = QPushButton('Cancel', newWindow)
button2.clicked.connect(cancel)
hbox = QHBoxLayout()
hbox.addWidget(button1)
hbox.addWidget(button2)
self.hbox = hbox
class Menu:
def __init__(self, menu: QMenu):
self.menu = menu
def addFun(self, name, p, lam):
action = QAction(name, p)
action.triggered.connect(lam)
self.menu.addAction(action)
def changeValue(sld, label):
text = f'ratio: {sld.value()}'
label.setText(text)
class PhotoProcessor(QMainWindow):
def __init__(self):
super().__init__()
self.labelImage = None
self.initUI()
def initUI(self):
self.labelImage = QLabel(self)
self.initMenu()
self.showMaximized()
def initMenu(self):
self.statusBar()
menuBar = self.menuBar()
fileMenu = menuBar.addMenu('File')
editMenu = menuBar.addMenu('Edit')
self.fileMenu = Menu(fileMenu)
self.editMenu = Menu(editMenu)
self.initFileMenu()
self.initEditMenu()
def initEditMenu(self):
self.editMenu.addFun('Rotate', self, lambda: self.noAsk(Photo.rotate))
self.editMenu.addFun('Vertical Mirror', self, lambda: self.noAsk(Photo.vertical_mirror))
self.editMenu.addFun('Horizontal Mirror', self, lambda: self.noAsk(Photo.horizontal_mirror))
self.editMenu.addFun('Resize', self, lambda: self.ask('ratio', 1, 500, 100, Photo.resize))
# wait for brightness
self.editMenu.addFun('Lightning', self, lambda: self.ask('value', -100, 100, 0, Photo.lighting))
# crash
self.editMenu.addFun('Contrast', self, lambda: self.ask('value', -100, 100, 0, Photo.contrast))
self.editMenu.addFun('Hue', self, lambda: self.ask('value', 0, 180, 0, Photo.hue))
blurMenu = self.editMenu.menu.addMenu('Blur')
self.blurMenu = Menu(blurMenu)
self.blurMenu.addFun('Blur', self, lambda: self.ask('value', 0, 20, 0, Photo.blur))
self.blurMenu.addFun('Median_Blur', self, lambda: self.ask('value', 0, 20, 0, Photo.median_blur))
self.blurMenu.addFun('gaussian_blur', self, lambda: self.ask('value', 0, 20, 0, Photo.gaussian_blur))
self.editMenu.addFun('Gray', self, lambda: self.noAsk(Photo.to_gray))
self.editMenu.addFun('Invert', self, lambda: self.noAsk(Photo.invert))
binaryMenu = self.editMenu.menu.addMenu('Binary')
self.binaryMenu = Menu(binaryMenu)
self.binaryMenu.addFun('Binary', self, lambda: self.ask('threshold', 0, 255, 127, Photo.to_binary))
self.binaryMenu.addFun('Binary_ostu', self, lambda: self.noAsk(Photo.to_binary_ostu))
self.binaryMenu.addFun('Binary_adaptive', self, lambda: self.noAsk(Photo.to_binary_adaptive))
self.editMenu.addFun('Sharpen', self, lambda: self.ask('value', 0, 20, 0, Photo.sharpen))
self.editMenu.addFun('Open', self, lambda: self.noAsk(Photo.open))
self.editMenu.addFun('Close', self, lambda: self.noAsk(Photo.close))
self.editMenu.addFun('Scale', self, lambda: self.noAsk(Photo.scale))
self.editMenu.addFun('Equalize', self, lambda: self.noAsk(Photo.equalizeHist))
self.editMenu.addFun('DetectAntigen', self, lambda: self.noAsk(Photo.detectQRcode))
def noAsk(self, func):
func(self.Image)
self.display_image()
def initFileMenu(self):
self.fileMenu.addFun('Open Image', self, self.openImage)
self.fileMenu.addFun('Save Image', self, self.saveImage)
self.fileMenu.addFun('Original Image', self, lambda: self.noAsk(Photo.origin))
def saveImage(self):
home_dir = str(Path.home())
filepath = QFileDialog.getSaveFileName(self, 'Save File', home_dir, 'Image files(*.jpg)')
if filepath[0]:
cv2.imwrite(filepath[0], self.Image.img)
def openImage(self):
home_dir = str(Path.home())
filepath = QFileDialog.getOpenFileName(self, 'Open Image', home_dir, "Image files(*.jpg *.png)")
if filepath[0]:
self.Image = Photo(filepath[0])
self.display_image()
def display_image(self):
shrink = cv2.cvtColor(self.Image.img, cv2.COLOR_BGR2RGB)
qt_img = QtGui.QImage(shrink.data,
shrink.shape[1],
shrink.shape[0],
shrink.shape[1] * 3,
QtGui.QImage.Format.Format_RGB888)
w, h = qt_img.width(), qt_img.height()
f1 = 1.0 * self.width() / w
f2 = 1.0 * self.height() / h
factor = min([f1, f2])
width = int(w * factor)
height = int(h * factor)
self.labelImage.setPixmap(QPixmap.fromImage(qt_img).scaled(width, height))
self.labelImage.resize(width, height)
# self.image_resize()
def image_resize(self):
w, h = self.labelImage.width(), self.labelImage.height()
f1 = 1.0 * self.width() / w
f2 = 1.0 * self.height() / h
factor = min([f1, f2])
width = int(w * factor)
height = int(h * factor)
self.labelImage.resize(width, height)
def cancel(self):
self.sender().parent().close()
def ask(self, text_, min_value, max_value, init, func):
newWindow = QDialog()
text = text_ + f': {init}'
vbox = QVBoxLayout()
label = QLabel(text, newWindow)
sld = QSlider(Qt.Orientation.Horizontal, newWindow)
sld.setMaximum(max_value)
sld.setMinimum(min_value)
sld.setTickPosition(QSlider.TickPosition.TicksAbove)
sld.setSliderPosition(init)
sld.setFocusPolicy(Qt.FocusPolicy.NoFocus)
sld.setGeometry(30, 40, 200, 30)
sld.valueChanged[int].connect(lambda: changeValue(sld, label))
judge = Judge(newWindow, lambda: self.setValue(sld, func), self.cancel)
vbox.addWidget(label)
vbox.addWidget(sld)
vbox.addLayout(judge.hbox)
newWindow.setLayout(vbox)
newWindow.show()
newWindow.exec()
def setValue(self, sld, fun):
a = self.sender()
b = a.parent()
b.close()
fun(self.Image, sld.value())
self.display_image()
def run():
app = QApplication(sys.argv)
pp = PhotoProcessor()
sys.exit(app.exec())
run()