1

我正在尝试使用 Python 2.7 和 Tkinker 循环播放 gif。它将在树莓派上运行,但我的实现甚至在我更强大的 Macbook pro 上也滞后。这是一个如何实现的示例:

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 帧的大小,这是可以预料的,但我相信我只是用预处理图像更新标签。有没有更有效的方法来做到这一点,所以 tkinter 不会滞后?

4

0 回答 0