2013-06-09 2 views
0

저는 Tkinter와 ImageTk를 사용하여 일련의 이미지를 표시하는 python 프로그램을 만들고 있습니다. 단일 이미지 이상을 표시 할 수 없었습니다. 다음은 오류를 재현하는 작은 완전한 프로그램입니다. 프로그램은 현재 jpg 파일을 직접 재귀 적으로 검색하고, use가 Enter 키를 누를 때이를 표시합니다.Tkinter로 이미지 표시

import Tkinter, ImageTk,os, re 


def ls_rec(direc): 
    try: 
     ls = os.listdir(direc) 
    except Exception as e: 
     return 
    for f in os.listdir(direc): 
     fpath = os.path.join(direc, f) 
     if os.path.isfile(fpath): 
      yield fpath 
     elif os.path.isdir(fpath): 
      for f2 in iterate_dir(os.path.join(direc,f)): 
       yield f2 

images = filter(lambda a:re.match('.*\\.jpg$',a),ls_rec(os.getcwd())) 
assert(len(images)>10) 
top = Tkinter.Tk() 
image_label = Tkinter.Label(top) 
Label_text = Tkinter.Label(top,text="Below is an image") 
img = None 
i = 0 



def get_next_image(event = None): 
    global i, img 
    i+=1 
    img = ImageTk.PhotoImage(images[i]) 
    label.config(image=img) 
    label.image = img 

top.bind('<Enter>',get_next_image) 
label.pack(side='bottom') 
Label_text.pack(side='top') 
get_next_image() 
top.mainloop() 

프로그램은 다음과 같은 역 추적 실패 :이 코드를 실행할 때

Traceback (most recent call last): 
    File "/usr/lib/python2.7/pdb.py", line 1314, in main 
    pdb._runscript(mainpyfile) 
    File "/usr/lib/python2.7/pdb.py", line 1233, in _runscript 
    self.run(statement) 
    File "/usr/lib/python2.7/bdb.py", line 387, in run 
    exec cmd in globals, locals 
    File "<string>", line 1, in <module> 
    File "/home/myuser/Projects/sample_images.py", line 1, in <module> 
    import Tkinter, ImageTk,os, re 
    File "/home/myuser/Projects/sample_images.py", line 32, in get_next_image 
    img = ImageTk.PhotoImage(some_image[1]) 
    File "/usr/lib/python2.7/dist-packages/PIL/ImageTk.py", line 109, in __init__ 
    mode = Image.getmodebase(mode) 
    File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 245, in getmodebase 
    return ImageMode.getmode(mode).basemode 
    File "/usr/lib/python2.7/dist-packages/PIL/ImageMode.py", line 50, in getmode 
    return _modes[mode] 
KeyError: '/home/myuser/sampleimage.jpg' 

사람이 같은 동작을 얻을 수 있습니까? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

편집 : korylprince의 솔루션, 청소의 비트를 사용하여, 다음은 원래 코드의 작업 버전은 다음과 같습니다

import os, re, Tkinter, ImageTk 

def ls_rec(direc, filter_fun=lambda a:True): 
    for (dirname, dirnames, fnames) in os.walk(direc): 
     for fname in fnames: 
      if filter_fun(fname): 
       yield os.path.join(dirname,fname) 


top = Tkinter.Tk() 
image_label = Tkinter.Label(top) 
text_label = Tkinter.Label(top,text="Below is an image") 
images = ls_rec(os.getcwd(), lambda a:re.match('.*\\.jpg$',a)) 

imgL = [] 

def get_next_image(event = None): 
    fname = images.next() 
    print fname 
    fhandle = open(fname) 
    img = ImageTk.PhotoImage(file=fhandle) 
    fhandle.close() 
    imgL.append(img) 
    image_label.config(image=img) 


top.bind('<Return>',get_next_image) 
image_label.pack(side='bottom') 
text_label.pack(side='top') 
get_next_image() 
top.mainloop() 

편집 : top.bind('<Enter>'...) 실제로보다는 프레임을 입력 마우스의 이벤트를 바인딩 사용자가 Enter 키를 누릅니다. 올바른 줄은 top.bind('<Return>',...)입니다.

+0

['glob()'] (http://docs.python.org/2/library/glob.html)을 사용하지 않는 이유가 있습니까? –

+0

아니, 방금 os.walk에 대해 알고 있었다. 내 개인 라이브러리에 구현 된 ls_rec을 가지고 있으므로 문제가되지 않습니다. 하지만 네, 글로브는 더 간단합니다. – erjoalgo

+0

사실 glob는 순환 적이 지 않습니다. 결국에는 이유가 있습니다. – erjoalgo

답변

3

ImageTk.PhotoImage은 실제로 제대로 문서화되지 않았습니다.

#outside of functions 
images = list() 

#inside function 
global images 
with open(images[i]) as f: 
    img = ImageTk.PhotoImage(file=f) 
    images.append(img) 

목록에서 이미지를 착용하는 이유는 그래서 파이썬에 대한 참조를 가질 것입니다 :

당신이 뭔가를 시도해야합니다. 그렇지 않으면 가비지 수집기가 결국 이미지 객체를 삭제합니다.

+0

동의합니다. 이 모듈 덕분에 많은 시간을 낭비했습니다. 나는 당신의 해결책을 시도했는데 그것은 원래의 오류를 제거했다. 이제는 자주 보는 다른 오류가 발생합니다. TclError : image "pyimage10"이 없습니다. 이 오류를 검색했습니다. 일부 사람들은 PhotoImages가 참조가 충분하지 않을 때 가비지 수집과 관련이 있다고 주장합니다. 하지만 이미 그 문제를 해결 한 것 같습니다. 지금은 무엇입니까? 왜 "이미지"pyimage10 "존재하지 않는"어떤 아이디어? 또한, img가 인스턴스화 된 후에 파일을 닫는 것이 가능한지 알고 있습니까? – erjoalgo

+0

방금 ​​내 대답을 업데이트했습니다. 기본적으로 이미지 객체에 열려있는 참조를 유지해야합니다. 그렇지 않으면 삭제됩니다. '''img''를 다시 바인딩하기 때문에 이미지가 삭제됩니다. – korylprince

+0

당신의 솔루션이 효과가있었습니다! 필자는 목록에있는 이미지를 전역 변수에 넣는 등의 작업을 시도했습니다. 한 번에 두 가지 오류가있는 것처럼 보였습니다. 나는 동시에 두 가지 오류를 해결하지 못했습니다. 감사합니다. – erjoalgo