2016-05-01 6 views
1

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.

  1. Ich habe versucht, die angebotene Lösung die Umsetzung von imgLoaded und imgCropLoaded in globale Variablen machen (siehe Code unten), aber es löst nicht mein Problem,
  2. 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,
  3. 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() 

Antwort

1

Getestet Code und es funktioniert, wie Sie es bestimmt. Sie haben nur vergessen, Ihr Canvas-Widget in Ihrem Hauptfenster zu platzieren. Das Hinzufügen einer crpImgCanvas.grid() oder crImgCanvas.pack() funktionierte für mich. Viel Glück!

+0

Vielen Dank :) – Aetos