Как сделать, чтобы при выборе определенного фильтра c помощью QRadioButton, данный фильтр применялся к загруженному изображению(pil)?

Выбранная фотография в QFileDialog появляется на экране, я хотел, чтобы при выборе одного из фильтров при нажатии на кнопку "Создать" этот фильтр был применен и сама картинка обновлялась на созданную.

Потом под фото должна будет появляться кнопка скачать, названия будут определенными. Когда будут выбраны фильтры 1 и 2(счет с 0), снизу будет появляться текстовое поле, в котором будет показано значение.

Я не понимаю как сделать все, что связано с применением фильтров к фото, ниже я оставлю ссылку на репозиторий (на всякий случай)

github

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 шт):

Автор решения: Armen Legran
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_())  # Запуск основного цикла приложения
→ Ссылка
Автор решения: S. Nick
  1. Пожалуйста, не дублируйте вопросы, а вносите необходимые изменения и дополнение в существующий вопрос.

  2. Лучше рассказывайте что вы хотите сделать.

  3. Один вопрос - это решение одной проблемы, а не напишите все действия по нажатию всех кнопок.

  4. Всегда приводите свои попытки решения проблемы.

  5. 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...')

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка