Outil de rognage d'image GUI réalisé avec Python + Tkinter

"Je veux un outil de découpage GUI qui fonctionne sur Python!"

Lorsqu'il s'agit d'images en Python, de nombreuses personnes peuvent vouloir les découper avec des opérations GUI.

J'ai cherché sur le net des articles utiles, mais c'est plutôt bien! Je n'ai rien pu rencontrer de tel, alors je vais le laisser ici.

introduction

Tkinter est un kit qui vous permet de créer facilement des outils d'interface graphique en Python. J'utilise habituellement Jupyter Notebook et j'utilise ipywidgets lorsque j'ai besoin d'une interface graphique, mais cela ne suffit pas et j'ai utilisé Tkinter cette fois.

Outil GUI pour découper un rectangle d'une image

Je vais découper une partie de l'image et l'enregistrer en Python. Je ne voulais pas juste faire cette partie de coupe Je voulais faire un processus comme [traitement d'image → rognage → traitement d'image]. La motivation pour cette époque était que je voulais le faire de manière cohérente avec Python.

Code et commentaire

code

crop.py


from tkinter import *
from PIL import Image
import os
os.chdir("c:\\users\\username")

#----------------------------------------------------------------------


def filenameMaker(num):
    return "%03d.png " % num


class MainWindow():

    #----------------

    def __init__(self, main):
        #Créer une toile pour afficher des images
        self.canvas = Canvas(main, width=200, height=200)
        self.canvas.grid(row=0, column=0, columnspan=2, rowspan=4)

        #image(000.png à 004.5 morceaux de png)Capturer
        self.my_images = []
        self.file_num = 0
        for i in range(0, 5):
            self.my_images.append(PhotoImage(file=filenameMaker(i)))
        self.my_image_number = 0

        #Sécurisez un numéro pour le stockage
        self.save_file_num = 0

        #Définir la première image
        self.image_on_canvas = self.canvas.create_image(
            0, 0, anchor=NW, image=self.my_images[self.my_image_number])

        #Faire divers boutons
        #Bouton pour afficher l'image suivante
        self.button_next = Button(
            main, text="Next", command=self.onNextButton, width=20, height=5)
        self.button_next.grid(row=2, column=4, columnspan=2, rowspan=2)
        #Bouton pour afficher l'image précédente
        self.button_back = Button(
            main, text="Back", command=self.onBackButton, width=20)
        self.button_back.grid(row=4, column=4, columnspan=2)
        #Bouton pour enregistrer la sélection
        self.button_save = Button(
            main, text="Save", command=self.onSaveButton, width=25, height=5)
        self.button_save.grid(row=2, column=6, columnspan=3, rowspan=2)
        #Bouton pour renvoyer un numéro de sauvegarde
        self.button_saveb = Button(
            main, text="Save Back", command=self.onSavebButton, width=25)
        self.button_saveb.grid(row=4, column=6, columnspan=3)

        #Faire une entrée pour afficher un message
        #Entrée pour afficher le numéro de l'image actuelle
        self.message_num = Entry(width=50)
        self.message_num.insert(
            END, ("This image is " + filenameMaker(self.my_image_number)))
        self.message_num.grid(row=6, column=4, columnspan=5)
        #Entrée pour afficher le prochain numéro de sauvegarde
        self.message = Entry(width=50)
        self.message.insert(END, ("Next save-name is " +
                                  "save-" + filenameMaker(self.save_file_num)))
        self.message.grid(row=7, column=4, columnspan=5)

        #Réserver des variables pour les curseurs
        self.left = 0
        self.right = 0
        self.top = 0
        self.bottom = 0

        #Tracez une ligne pour le recadrage de l'image sur la toile
        self.canvas.create_line(self.left, 0, self.left,
                                200, tag="left_line", fill='green')
        self.canvas.create_line(self.right, 0, self.right,
                                200, tag="right_line", fill='red')
        self.canvas.create_line(
            0, self.top, 200, self.top, tag="top_line", fill='green')
        self.canvas.create_line(0, self.bottom, 200,
                                self.bottom, tag="bottom_line", fill='red')

        #Créer un curseur pour le recadrage d'image
        self.left = Scale(main, label='left', orient='h',
                          from_=0, to=200, length=200, command=self.onSliderLeft)
        self.left.grid(row=4, column=0, columnspan=2, rowspan=2)

        self.right = Scale(main, label='right', orient='h',
                           from_=0, to=200, length=200, command=self.onSliderRight)
        self.right.grid(row=6, column=0, columnspan=2, rowspan=2)

        self.top = Scale(main, label='top', orient='v',
                         from_=0, to=200, length=200, command=self.onSliderTop)
        self.top.grid(row=4, column=2, rowspan=4)

        self.bottom = Scale(main, label='bottom', orient='v',
                            from_=0, to=200, length=200, command=self.onSliderBottom)
        self.bottom.grid(row=4, column=3, rowspan=4)

        #Déplacez la ligne pour le recadrage de l'image en fonction de l'image affichée
        self.left.set(0)
        self.right.set(self.my_images[self.my_image_number].width())
        self.top.set(0)
        self.bottom.set(self.my_images[self.my_image_number].height())

    #----------------

    def onBackButton(self):
        #Revenir à la dernière image
        if self.my_image_number == 0:
            self.my_image_number = len(self.my_images) - 1
        else:
            #Revenir en arrière
            self.my_image_number -= 1

        #Mettre à jour l'image d'affichage
        self.canvas.itemconfig(self.image_on_canvas,
                               image=self.my_images[self.my_image_number])

        #Mise à jour de la position de la ligne pour découper l'image en fonction de l'image affichée
        self.left.set(0)
        self.right.set(self.my_images[self.my_image_number].width())
        self.top.set(0)
        self.bottom.set(self.my_images[self.my_image_number].height())


        #Mettre à jour le contenu de l'entrée
        self.message_num.delete(0, END)
        self.message_num.insert(
            END, ("This image is " + filenameMaker(self.my_image_number)))

    def onNextButton(self):
        #Faites un pas en avant
        self.my_image_number += 1

        #Revenir à la première image
        if self.my_image_number == len(self.my_images):
            self.my_image_number = 0

        #Mettre à jour l'image d'affichage
        self.canvas.itemconfig(self.image_on_canvas,
                               image=self.my_images[self.my_image_number])

        #Mise à jour de la position de la ligne pour découper l'image en fonction de l'image affichée
        self.left.set(0)
        self.right.set(self.my_images[self.my_image_number].width())
        self.top.set(0)
        self.bottom.set(self.my_images[self.my_image_number].height())

        #Mettre à jour le contenu de l'entrée
        self.message_num.delete(0, END)
        self.message_num.insert(
            END, ("This image is " + filenameMaker(self.my_image_number)))

    def onSaveButton(self):
        #Capturer l'image d'affichage
        self.temp_image = Image.open(filenameMaker(self.my_image_number))
        #Découper à la position sélectionnée
        self.cropped_image = self.temp_image.crop(
            (self.left.get(), self.top.get(), self.right.get(), self.bottom.get()))
        #sauvegarder
        self.cropped_image.save("save-" + filenameMaker(self.save_file_num))

        self.save_file_num += 1

        #Mettre à jour le contenu de l'entrée
        self.message.delete(0, END)
        self.message.insert(END, ("Next save-name is " +
                                  "save-" + filenameMaker(self.save_file_num)))

    def onSavebButton(self):
        self.save_file_num -= 1

        if self.save_file_num == -1:
            self.save_file_num = 0

        #Mettre à jour le contenu de l'entrée
        self.message.delete(0, END)
        self.message.insert(END, ("Next save-name is " +
                                  "save-" + filenameMaker(self.save_file_num)))

    def onSliderLeft(self, args):
        # change line
        self.canvas.delete("left_line")
        self.canvas.create_line(
            self.left.get(), 0, self.left.get(), 200, tag="left_line", fill='green')

    def onSliderRight(self, args):
        # change line
        self.canvas.delete("right_line")
        self.canvas.create_line(
            self.right.get(), 0, self.right.get(), 200, tag="right_line", fill='red')

    def onSliderTop(self, args):
        # change line
        self.canvas.delete("top_line")
        self.canvas.create_line(0, self.top.get(), 200,
                                self.top.get(), tag="top_line", fill='green')

    def onSliderBottom(self, args):
        # change line
        self.canvas.delete("bottom_line")
        self.canvas.create_line(0, self.bottom.get(), 200,
                                self.bottom.get(), tag="bottom_line", fill='red')


#----------------------------------------------------------------------

root = Tk()
MainWindow(root)
root.mainloop()

Commentaire

L'écran d'exécution est illustré ci-dessous. Le contenu de l'opération consiste à sélectionner la position de découpe avec chaque curseur Afficher l'image suivante avec le bouton Suivant Afficher l'image précédente avec le bouton Retour Enregistrez la plage de découpe avec le bouton Enregistrer Cliquez sur le bouton Enregistrer en arrière pour enregistrer un numéro d'image 図1.png

Chaque widget est créé avec def __init __ (self, main): pour définir la position d'affichage. .Grid est utilisé pour définir la position d'affichage. Lors du chargement d'une image, j'utilise PhotoImage et lors de l'enregistrement avec def onSaveButton (self):, j'utilise ʻImage de PIL, qui semble gênant, mais c'est une découpe rectangulaire avec PhotoImage. Je ne pouvais pas le faire, et je ne pouvais pas bien le lire avec ʻImage.

↓ Image enregistrée. save-000.png

Site référencé

--Essayez d'utiliser Tkinter de Python --Qiita http://qiita.com/nnahito/items/ad1428a30738b3d93762

--Introduction à Easy Python / Tkinter http://www.geocities.jp/m_hiroi/light/pytk01.html

Recommended Posts

Outil de rognage d'image GUI réalisé avec Python + Tkinter
[Python] Python et sécurité-② Outil d'analyse de port réalisé avec Python
J'ai créé une application graphique avec Python + PyQt5
[Python] J'ai créé un téléchargeur Youtube avec Tkinter.
Traitement d'image avec Python
Création d'un outil de vente simple avec Python GUI: création de devis
Traitement d'image avec Python (partie 2)
Programmation avec Python et Tkinter
Édition d'image avec python OpenCV
J'ai fait un blackjack avec du python!
Tri des fichiers image avec Python (2)
Tri des fichiers image avec Python (3)
Créer une visionneuse d'images avec Tkinter
Traitement d'image avec Python (partie 1)
[GUI en Python] PyQt5-Layout management-
Tweet avec image en Python
Tri des fichiers image avec Python
Traitement d'image avec Python (3)
Exécuter Label avec tkinter [Python]
J'ai fait un blackjack avec Python.
[GUI avec Python] PyQt5-Préparation-
Othello fait avec python (comme GUI)
J'ai créé wordcloud avec Python.
[Python] Traitement d'image avec scicit-image
[GUI avec Python] PyQt5 -Paint-
J'ai fait un jeu de frappe simple avec tkinter de Python
Solution lorsque l'image ne peut pas être affichée avec tkinter [python]
Création d'un outil de vente simple avec Python GUI: recherche de numéro d'employé
[Je l'ai fait avec Python] Outil pour la sortie par lots de données XML
Créer une interface graphique aussi facilement que possible avec python [édition tkinter]
J'ai fait un jeu de puzzle (comme) avec Tkinter of Python
Création d'un outil de vente simple avec l'interface graphique Python: calcul du taux de coût
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
Création d'outils de vente simple avec l'interface graphique Python: application de bureau publiée
Découpez une image avec python
Bases de SNS Python faites avec Flask
[Python] Utilisation d'OpenCV avec Python (filtrage d'image)
Créer une interface graphique python à l'aide de tkinter
Faisons une interface graphique avec python.
Numer0n avec des objets fabriqués avec Python
J'ai fait une loterie avec Python.
[GUI avec Python] PyQt5-La première étape-
Traitement d'image avec la binarisation Python 100 knocks # 3
Application GUI facile avec Tkinter Text
[GUI en Python] PyQt5-Glisser-déposer-
Développement de jeux Othello avec Python
Faisons du scraping d'images avec Python
Trouver la similitude d'image avec Python + OpenCV
100 traitement d'image par Python Knock # 2 Échelle de gris
[GUI avec Python] PyQt5-Widget personnalisé-
J'ai créé un démon avec Python
[Python] Création de plusieurs fenêtres avec Tkinter
Envoyer l'image avec python et enregistrer avec php
Génération d'images dégradées avec Python [1] | np.linspace
Création d'interface graphique en python avec tkinter 2
Jeu de vie avec Python [je l'ai fait] (sur terminal et Tkinter)
Différence de comportement du cadre transparent réalisé avec tkinter dans pyinstaller [Python]
[Python] J'ai créé une visionneuse d'images avec une fonction de tri simple.
Lecture vidéo avec son sur python !! (tkinter / imageio)
Bases du traitement d'images binarisées par Python
Traitement d'image par Python 100 knock # 10 filtre médian