如何防止gif在tkinter中冻结?

2024-04-18 07:42:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用python2.7和Tkinker在循环中播放gif。它是运行在树莓皮,但我的实现是落后的,甚至在我更强大的MacBookPro。下面是一个如何实现的示例:

frames= [] #holds gif images
weatherIND = 0 #frame of gif currently being displayed


#processes and initializes gif, then starts the loop 
def getWeather() 
   global frames

   frames= []
   self.processImage("assets/Rain.gif")
   print("frames len = " + str(len(frames)))

   Photo = frames[0] #initialize 

   self.iconLbl.config(image=Photo)
   self.iconLbl.image = Photo
   self.after(0, self.update) #start the loop

#displays the next frame of the gif every 20 ms 
def update(self):
    global weatherInd
    global frames

    if weatherInd == (len(frames)):
        weatherInd = 0
    Photo = frames[weatherInd]

    self.iconLbl.config(image=Photo)
    self.iconLbl.image = Photo

    weatherInd+=1

    self.after(20, self.update)


#takes a gif and puts each frame in a list as a PhotoImage object
def processImage(self, path):
    '''
    Iterate the GIF, extracting each frame.
    '''
    global frames

    mode = 'global'

    im = Image.open(path)

    i = 0
    p = im.getpalette()
    last_frame = im.convert('RGBA')

    try:
        while True:
            print "saving %s (%s) frame %d, %s %s" % (path, mode, i, im.size, im.tile)

            '''
            If the GIF uses local colour tables, each frame will have its own palette.
            If not, we need to apply the global palette to the new frame.
            '''
            if not im.getpalette():
                im.putpalette(p)

            new_frame = Image.new('RGBA', im.size)

            '''
            Is this file a "partial"-mode GIF where frames update a region of a different size to the entire image?
            If so, we need to construct the new frame by pasting it on top of the preceding frames.
            '''
            if mode == 'partial':
                new_frame.paste(last_frame)

            new_frame.paste(im, (0,0), im.convert('RGBA'))


            new_frame = new_frame.resize((100,100), Image.ANTIALIAS)
            Photo = ImageTk.PhotoImage(new_frame)
            frames.append(Photo)

            i += 1
            last_frame = new_frame
            im.seek(im.tell() + 1)
    except EOFError:
        pass

现在的问题是,当gif播放时,每5-10秒它就会挂在一帧上1/2-1秒。如果我尝试每20毫秒处理一次gif帧或调整其大小,这是意料之中的,但我相信我只是用预处理的图像更新标签。有没有更有效的方法让特金特不会落后?你知道吗


Tags: oftheimageselfnewframesmodeupdate