"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.
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.
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.
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()
filenameMaker (num)
. (2017.04.07)
ʻAutopep8 -i crop.py`. (2017.04.07)
Suppression du code inutile. (09/04/2017)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
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.
--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