Как сделать, чтобы при выборе определенного фильтра c помощью QRadioButton, данный фильтр применялся к загруженному изображению(pil)?
Выбранная фотография в QFileDialog появляется на экране, я хотел, чтобы при выборе одного из фильтров при нажатии на кнопку "Создать" этот фильтр был применен и сама картинка обновлялась на созданную.
Потом под фото должна будет появляться кнопка скачать, названия будут определенными. Когда будут выбраны фильтры 1 и 2(счет с 0), снизу будет появляться текстовое поле, в котором будет показано значение.
Я не понимаю как сделать все, что связано с применением фильтров к фото, ниже я оставлю ссылку на репозиторий (на всякий случай)
main.py
class AppMain(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
uic.loadUi('ui/main.ui', self)
self.initUI()
def initUI(self):
self.setWindowTitle('TEST')
self.pushButton_2.clicked.connect(self.showDialog)
self.radioButton_3.clicked.connect(self.showPix1)
self.radioButton_2.clicked.connect(self.showPix)
self.radioButton.clicked.connect(self.closePix)
self.radioButton_4.clicked.connect(self.closePix)
self.label.close()
self.lineEdit.close()
self.pushButton_3.close()
self.pushButton.clicked.connect(self.izmPhoto)
def showDialog(self):
fname = QtWidgets.QFileDialog.getOpenFileName(
self, 'Выбрать картинку', '',
'Картинка (*.jpg *.jpeg *.png *.gif)')
print(fname)
imagePath = fname[0]
pixmap = QtGui.QPixmap(imagePath)
self.picture.setPixmap(QtGui.QPixmap(pixmap))
def showPix(self):
self.label.show()
self.label.setText('Количеств пикселей : ')
self.lineEdit.show()
def showPix1(self):
self.label.show()
self.label.setText('Изменить на : ')
self.lineEdit.show()
def closePix(self):
self.label.close()
self.lineEdit.close()
def izmPhoto(self):
# здесь по идее должно быть изменение фото
pass
main.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>964</width>
<height>642</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">*{
background-color: rgb(239, 243, 255);
}
QLineEdit{
margin-bottom:10px;
height:20px;
border:2px solid rgb(0, 0, 127);
border-radius:5px;
background-color: rgb(239, 243, 255);
font-size:14px;
padding:5px;
}
QPushButton{
border-radius:5px;
background:qlineargradient(spread:pad, x1:0, y1:0.574, x2:1, y2:0, stop:0 rgba(13, 0, 99, 255), stop:1 rgba(23, 0, 237, 255));
padding:5px;
color:#fff;
width:100%;
}
QPushButton:hover{
border: 2px solid rgb(0, 170, 255);
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="font">
<font>
<family>Calibri</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Выбрать файл</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="picture">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="styleSheet">
<string notr="true">QLabel{
padding-top:5px;
}</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="font">
<font>
<family>Calibri</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Сохранить</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="horizontalSpacing">
<number>25</number>
</property>
<item row="0" column="0">
<widget class="QRadioButton" name="radioButton">
<property name="font">
<font>
<family>Calibri</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Поменять местами цвета пикселей</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="radioButton_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Calibri</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Размыть фото</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QRadioButton" name="radioButton_4">
<property name="font">
<font>
<family>Calibri</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Сделать фото черно-белым</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QRadioButton" name="radioButton_3">
<property name="font">
<font>
<family>Calibri</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Изменить цвет пикселей</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<family>Calibri</family>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Количество пикселей :</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="2" column="0" colspan="4">
<widget class="QPushButton" name="pushButton">
<property name="font">
<font>
<family>Calibri</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Создать</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
Ответы (2 шт):
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QRadioButton, QLabel, QFileDialog
from PyQt5.QtGui import QPixmap
from PIL import Image, ImageFilter, ImageEnhance
class ImageFilterApp(QWidget):
def __init__(self):
super().__init__()
self.image_path = None # Путь к изображению
self.initUI() # Инициализация пользовательского интерфейса
def initUI(self):
layout = QVBoxLayout() # Создание вертикального макета
self.setLayout(layout) # Установка макета для виджета
self.label = QLabel() # Метка для отображения изображения
layout.addWidget(self.label) # Добавление метки в макет
self.btn_load = QPushButton('Загрузить img') # Кнопка для загрузки изображения
self.btn_load.clicked.connect(self.load_image) # Подключение функции загрузки изображения к кнопке
layout.addWidget(self.btn_load) # Добавление кнопки в макет
self.radio1 = QRadioButton('Оттенки серого') # Радиокнопка для применения фильтра "Оттенки серого"
self.radio1.clicked.connect(self.apply_filter) # Подключение функции применения фильтра к радиокнопке
layout.addWidget(self.radio1) # Добавление радиокнопки в макет
self.radio2 = QRadioButton('Размытие') # Радиокнопка для применения фильтра "Размытие"
self.radio2.clicked.connect(self.apply_filter) # Подключение функции применения фильтра к радиокнопке
layout.addWidget(self.radio2) # Добавление радиокнопки в макет
self.radio3 = QRadioButton('Повышение резкости') # Радиокнопка для применения фильтра "Повышение резкости"
self.radio3.clicked.connect(self.apply_filter) # Подключение функции применения фильтра к радиокнопке
layout.addWidget(self.radio3) # Добавление радиокнопки в макет
self.btn_save = QPushButton('Скачать') # Кнопка для сохранения изображения
self.btn_save.clicked.connect(self.save_image) # Подключение функции сохранения изображения к кнопке
layout.addWidget(self.btn_save) # Добавление кнопки в макет
def load_image(self):
self.image_path, _ = QFileDialog.getOpenFileName() # Открытие диалогового окна для выбора файла
if self.image_path: # Если путь к файлу существует
self.label.setPixmap(QPixmap(self.image_path)) # Загрузка изображения в метку
def apply_filter(self):
if self.image_path: # Если путь к файлу существует
image = Image.open(self.image_path) # Открытие изображения
if self.radio1.isChecked(): # Если выбран фильтр "Оттенки серого"
image = image.convert('L') # Применение фильтра "Оттенки серого"
elif self.radio2.isChecked(): # Если выбран фильтр "Размытие"
image = image.filter(ImageFilter.BLUR) # Применение фильтра "Размытие"
elif self.radio3.isChecked(): # Если выбран фильтр "Повышение резкости"
image = ImageEnhance.Sharpness(image).enhance(2.0) # Применение фильтра "Повышение резкости"
image.save('temp.png') # Сохранение изображения
self.label.setPixmap(QPixmap('temp.png')) # Загрузка изображения в метку
def save_image(self):
if self.image_path: # Если путь к файлу существует
save_path, _ = QFileDialog.getSaveFileName() # Открытие диалогового окна для сохранения файла
if save_path: # Если путь для сохранения существует
Image.open('temp.png').save(save_path + '.png') # Сохранение изображения
if __name__ == '__main__':
app = QApplication(sys.argv) # Создание приложения
ex = ImageFilterApp() # Создание экземпляра класса ImageFilterApp
ex.show() # Отображение окна приложения
sys.exit(app.exec_()) # Запуск основного цикла приложения
Пожалуйста, не дублируйте вопросы, а вносите необходимые изменения и дополнение в существующий вопрос.
Лучше рассказывайте что вы хотите сделать.
Один вопрос - это решение одной проблемы, а не напишите все действия по нажатию всех кнопок.
Всегда приводите свои попытки решения проблемы.
Qt очень самодостаточный. Вот некоторые варианты без модуля PIL:
main.py
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic # +
from PyQt5.QtGui import QImage, qRgba, QPixmap # +
from check_db import *
import random
class AppMain(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
uic.loadUi('ui/main.ui', self)
self.initUI()
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.imagePath = None
self.original = QtWidgets.QLabel()
self.radioButton.setText('Negative')
self.radioButton_2.setText('Original')
self.radioButton_4.setText('Gray scale')
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def initUI(self):
self.setWindowTitle('TEST')
self.pushButton_2.clicked.connect(self.showDialog)
self.radioButton_3.clicked.connect(self.showPix1)
self.radioButton_2.clicked.connect(self.showPix)
self.radioButton.clicked.connect(self.closePix)
self.radioButton_4.clicked.connect(self.closePix)
self.label.close()
self.lineEdit.close()
self.pushButton_3.close()
self.pushButton.clicked.connect(self.izmPhoto)
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def showDialog(self):
imagePath, ok = QtWidgets.QFileDialog.getOpenFileName(
self, 'Выбрать картинку', '',
'Картинка (*.jpg *.jpeg *.png *.gif)')
print(f'def showDialog(fname): {imagePath}')
if imagePath:
pixmap = QtGui.QPixmap(imagePath)
self.picture.setPixmap(QtGui.QPixmap(pixmap))
self.imagePath = imagePath
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def showPix(self):
self.label.show()
self.label.setText('Количеств пикселей : ')
self.lineEdit.show()
def showPix1(self):
self.label.show()
self.label.setText('Изменить на : ')
self.lineEdit.show()
def closePix(self):
self.label.close()
self.lineEdit.close()
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def izmPhoto(self):
# здесь по идее должно быть изменение фото
if not self.imagePath:
print(f'\nнет фото для изменения') #
return
pixmap = QtGui.QPixmap(self.imagePath) # !!! +++
self.original.setPixmap(pixmap) # !!! +++
if self.radioButton.isChecked():
print(f'radioButton {self.radioButton.text()}')
self.toNegative() # !!! +++
elif self.radioButton_2.isChecked():
self.asOriginal() # !!! +++
print(f'radioButton_2 {self.radioButton_2.text()}')
print(f'{self.lineEdit.text()}; {self.label.text()}')
if not self.lineEdit.text():
return
elif self.radioButton_3.isChecked():
print(f'radioButton_3 {self.radioButton_3.text()}')
print(f'{self.lineEdit.text()}; {self.label.text()}')
if not self.lineEdit.text():
return
elif self.radioButton_4.isChecked():
print(f'radioButton_4 {self.radioButton_4.text()}')
self.toGray() # !!! +++
else:
print(f'Сделайте выбор того, что вы хотите сделать. !!!!!!')
return
def toGray(self):
image = self.original.pixmap().toImage()
transformed = image.convertToFormat(QtGui.QImage.Format_Grayscale8)
self.picture.setPixmap(QtGui.QPixmap.fromImage(transformed))
def toNegative(self):
image = self.original.pixmap().toImage()
image.invertPixels()
self.picture.setPixmap(QtGui.QPixmap.fromImage(image))
def asOriginal(self):
self.picture.setPixmap(self.original.pixmap())
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class Loading(QtWidgets.QWidget):
def __init__(self, *args):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Загрузка...')
self.setFixedSize(800, 600)
self.label_animation = QtWidgets.QLabel(self)
self.movie = QtGui.QMovie('img/loader.gif')
self.label_animation.setMovie(self.movie)
timer = QtCore.QTimer(self)
self.startAnimation()
timer.singleShot(4900 + random.randrange(500), self.stopAnimation)
self.show()
def startAnimation(self):
self.movie.start()
def stopAnimation(self):
self.appMain = AppMain()
self.appMain.show()
self.movie.stop()
self.close()
class App(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
uic.loadUi('ui/vhod.ui', self)
self.loading_flag = False
self.initUI()
self.fio.setFocus()
def initUI(self):
self.setWindowTitle('Вход / Регестрация ?')
self.setFixedSize(750, 550)
self.reg_2.clicked.connect(self.registration)
self.vhod_2.clicked.connect(self.auth)
self.check_db = CheckThread(self)
self.check_db.mysignal.connect(self.on_signal)
def on_signal(self, text):
if text == 'Ok':
self.loading_flag = True
else:
self.loading_flag = False
def registration(self):
fio = self.fio.text()
email = self.email.text()
pas = self.pas.text()
if not email or not pas or not fio:
msg = QtWidgets.QMessageBox.information(self, 'Внимание', 'Заполните все поля ввода.')
return
self.check_db.thr_reg(fio, email, pas)
def auth(self):
email = self.email_2.text()
pas = self.pas_2.text()
if not email or not pas:
msg = QtWidgets.QMessageBox.information(self, 'Внимание', 'Заполните все поля ввода.')
return
self.check_db.thr_login(email, pas)
if self.loading_flag:
self.loading = Loading(self)
self.loading.show()
self.close()
else:
msg = QtWidgets.QMessageBox.information(self, 'Внимание', 'Что-то пошло не так.')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon('img/logo.png'))
ex = App()
ex.show()
try:
sys.exit(app.exec())
except SystemExit:
print('Closing Window...')



