Mein Code soll ein Bild in ein TopLevel-Fenster laden, das eine Leinwand enthält, dann sollte ich aus diesem geladenen Bild über ein paar Koordinaten ein Rechteck in diesem Bild auswählen. Die Auswahl sollte auf der Arbeitsfläche der Haupt-GUI erscheinen.Tkinter, PIL, Bild wird nicht geladen mit Crop
Ich habe ein paar Themen besucht, die das gleiche Problem haben könnten wie ich, such as this one.
- Ich habe versucht, die angebotene Lösung die Umsetzung von
imgLoaded
undimgCropLoaded
in globale Variablen machen (siehe Code unten), aber es löst nicht mein Problem, - Hinweis in meinem Code, der die Variable
idCrop = cropCanvas.create_image(0,0,anchor='nw',image=imgCropLoaded)
den Wert annimmt 1 während des Debuggens, so wirklich das einzige Problem ist das Bild nicht angezeigt, - Wenn Sie meinen Code testen möchten: Führen Sie es aus, dann laden Sie ein JPEG/.jpg Bild. Sobald es geladen ist, können Sie versuchen, darauf zu klicken (im zweiten Fenster) und ein Rechteck zu ziehen, um die Auswahl zu treffen. Die Koordinaten der oberen linken und unteren rechten Punkte werden in der Konsole angezeigt.
Hier ist mein Code (Ich bin immer noch ein Neuling in Python und Tkinter)
from _functools import partial
from tkinter import Tk, Menu, Canvas, Frame, Toplevel
from tkinter.filedialog import askopenfilename
from PIL import ImageTk, Image
#Variables globales
xSelectHG=0
ySelectHG=0
xSelectBD=0
ySelectBD=0
#last Rectangle Id
idRectangle = 0
#Image files references from PhotoImage
imgLoaded = 0
imgCropLoaded = 0
# Functions
def deleteRectangle(canvas,id):
canvas.delete(id)
return
def startSelectPortion(event):
global xSelectHG
xSelectHG = event.x
global ySelectHG
ySelectHG = event.y
#print("[X,Y]Hg=",xSelectHG, ySelectHG)
return
def stopSelectPortion(imgFile,cropCanvas,canvas,event):
#Delete previous rectangle
global idRectangle
deleteRectangle(canvas, idRectangle)
global xSelectBD
xSelectBD = event.x
global ySelectBD
ySelectBD = event.y
#print("[X,Y]BD=",xSelectBD, ySelectBD)
#print("[X,Y]BD=",xSelectBD, ySelectBD)
startCrop(imgFile,cropCanvas,canvas)
return
def startCrop(imgFile, cropCanvas, canvas):
#Cropping an image
#Crop box:
#global xSelectHG, ySelectHG, xSelectBD, ySelectBD
print("[X,Y]Hg=",xSelectHG, ySelectHG)
print("[X,Y]BD=",xSelectBD, ySelectBD)
cropBox = (xSelectHG,ySelectHG,xSelectBD,ySelectBD)
imgCrop = imgFile.crop(cropBox)
global imgCropLoaded
imgCropLoaded = ImageTk.PhotoImage(imgCrop)
#Keeping a reference of the loaded image
cropCanvas.image = imgCropLoaded
cropCanvas.config(height=imgCrop.size[0],width=imgCrop.size[1])
#This idCrop seems to be 1 during debuggin, so the image loads successfully, but it doesn't get displayed.
idCrop = cropCanvas.create_image(0,0,anchor='nw',image=imgCropLoaded)
global idRectangle
idRectangle=canvas.create_rectangle(xSelectHG,ySelectHG,xSelectBD,ySelectBD)
canvas.update()
cropCanvas.update()
return
def openImage(topLevel,canvas, cropCanvas):
imgFormats = [("JPEG","*.jpg")]
imgName = askopenfilename(filetypes=imgFormats,title="Please choose an image of JPEG format")
imgFile = Image.open(imgName)
global imgLoaded
imgLoaded = ImageTk.PhotoImage(imgFile)
canvas.config(height=imgFile.size[0], width=imgFile.size[1])
#Keeping a reference of the loaded image
canvas.img = imgLoaded
canvas.create_image(0,0,anchor='nw',image=imgLoaded)
canvas.grid(row=0,columns=1)
canvas.bind('<Button-1>',partial(startSelectPortion))
canvas.bind('<ButtonRelease-1>',partial(stopSelectPortion, imgFile, cropCanvas, canvas))
return
def quit():
gui.destroy()
return
gui = Tk()
#How to make this top level appear only when I click the button?
imgTopLevel = Toplevel(gui)
imgCanvas = Canvas(imgTopLevel, height=100, width=100)
crpImgCanvas = Canvas(gui,height=100,width=100)
menubar = Menu(gui)
filemenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="Files", menu=filemenu)
filemenu.add_command(label="Open", command=partial(openImage, imgTopLevel,imgCanvas,crpImgCanvas))
menubar.add_separator()
menubar.add_command(label="Quit", command=partial(quit))
gui.config(menu=menubar)
gui.mainloop()
Vielen Dank :) – Aetos