Trying to Load an Image with Dialogue Box in Python and Display it in a Layer - PYTHON 3.4 using Tkinter and PIL -


i trying make simple photo editor. got functions editing photos. trying make nice gui. when user presses file>open, open dialogue box comes , can choose image. want image load inside of layer in gui.

here code far: p.s. when put code inside open_img function outise function, works, when put inside function, no image loads

import os tkinter import * import tkinter.messagebox pil import image, imagetk tkinter.filedialog import askopenfilename   def g_quit():     mexit=tkinter.messagebox.askyesno(title="quit", message="are sure?")     if mexit>0:         mgui.destroy()         return  #open menu def open_img():     file = tkinter.filedialog.askopenfilename(initialdir='d:/users/')     w_box = 500     h_box = 500      pil_image = image.open(file)      w, h = pil_image.size      pil_image_resized = resize(w, h, w_box, h_box, pil_image)     # wr, hr = pil_image_resized.size      tk_image = imagetk.photoimage(pil_image_resized)      label2.config(image=tk_image, width=w_box, height=h_box)  def resize(w, h, w_box, h_box, pil_image):     '''     resize pil_image object fit     box of size w_box times h_box, retain aspect ratio     '''     f1 = 1.0*w_box/w  # 1.0 forces float division in python2     f2 = 1.0*h_box/h     factor = min([f1, f2])     #print(f1, f2, factor)  # test     # use best down-sizing filter     width = int(w*factor)     height = int(h*factor)     return pil_image.resize((width, height), image.antialias)    mgui = tk() mgui.title('photo filters') mgui.geometry('650x500') mgui.resizable(0, 0) #disable resizeability photoframe = frame(mgui, bg="orange", width=500, height=500) photoframe.pack(side=left) filtersframe = frame(mgui, bg="yellow", width=150, height=500) filtersframe.pack(side=left, fill=y) label2 = label(photoframe)  #create buttons possible filters negative_btn = button(filtersframe, text="negative") negative_btn.pack()  weighted_grayscale_btn = button(filtersframe, text="weighted grayscale") weighted_grayscale_btn.pack()  solarize_btn = button(filtersframe, text="solarize") solarize_btn.pack()  black_and_white_btn = button(filtersframe, text="black , white") black_and_white_btn.pack()  black_and_white_and_gray_btn = button(filtersframe, text="black , white , gray") black_and_white_and_gray_btn.pack()  extreme_contrast_btn = button(filtersframe, text="extreme contrast") extreme_contrast_btn.pack()  sepia_tint_btn = button(filtersframe, text="sepia tint") sepia_tint_btn.pack()  adjust_component_btn = button(filtersframe, text="adjusts components") adjust_component_btn.pack()  posterize_btn = button(filtersframe, text="posterize") posterize_btn.pack()  simplify_btn = button(filtersframe, text="simplify") simplify_btn.pack()  detect_edges_btn = button(filtersframe, text="detect edges") detect_edges_btn.pack()  detect_edges_better_btn = button(filtersframe, text="detect edges better") detect_edges_better_btn.pack()  blur_btn = button(filtersframe, text="blur") blur_btn.pack()  flip_image = button(filtersframe, text="flip horizontal") flip_image.pack()    #menu bar menubar = menu(mgui) filemenu = menu(menubar) #create menu options go under drop down filemenu.add_command(label="new") filemenu.add_command(label="open", command=open_img) filemenu.add_command(label="save as") filemenu.add_command(label="close", command=g_quit) #create main button (e.g file) contains drop down options menubar.add_cascade(label="file", menu=filemenu) mgui.config(menu=menubar) mgui.mainloop() 

you've got 2 problems here. 1 of them, found yourself—you never call label2.pack(), label never gets displayed. but, after fix that, label blank.

as label documentation says:

you can use label display photoimage , bitmapimage objects. when doing this, make sure keep reference image object, prevent being garbage collected python’s memory allocator.

you're not doing that. store photoimage in local variable, tk_image, goes away function exits.

that should explain why works if move code outside function. if that, tk_image becomes global variable, doesn't go away until whole program exits. and, since you're using global variables on place implicitly, 1 possible fix use explicit global this:

def open_img():     global tk_image     # rest of code 

however, better trick cram image attribute of else that's going stick around, label object itself:

def open_img():     # existing code     label2.tk_image = imagetk.photoimage(pil_image_resized)     label2.config(image=label2.tk_image, width=w_box, height=h_box) 

now, image can't garbage collected until label that's using gets garbage collected (or until replace new image).

in fact, @ docs, example of using photoimage label does:

photo = photoimage(file="icon.gif") w = label(parent, image=photo) w.photo = photo w.pack() 

Comments

Popular posts from this blog

c++ - QTextObjectInterface with Qml TextEdit (QQuickTextEdit) -

javascript - angular ng-required radio button not toggling required off in firefox 33, OK in chrome -

xcode - Swift Playground - Files are not readable -