GIF-анимация PIL, но некоторые кадры черные - PullRequest
3 голосов
/ 11 июля 2011

Я пытался анимировать изображения внутри программы чата автоматически, используя PIL и Tkinter в Python. Иногда они работают, но в большинстве случаев они этого не делают. Я предоставлю изображения, которые работают, и те, которые не

По сути, я анимирую изображения, вызывая ImageTk.PhotoImage для каждого изображения в последовательности GIF, и анимация запускается путем обновления виджетов меток с помощью вызова root.after. Анимация работает довольно плавно

Однако моя проблема в том, что большинство анимированных GIF-файлов, которые я пытаюсь запустить, повреждены или что-то в этом роде. обычно первый кадр в порядке, но остальные либо полностью черные, либо полны артефактов.

Это изображения:

Это один из немногих, который работает: http://fc02.deviantart.net/fs42/f/2009/061/d/8/d856ba6223c66ce347c6c814f67d307b.gif

Эти вспышки черные:

http://fc02.deviantart.net/fs70/f/2010/007/c/3/_mekolai__by_Pyritie.gif http://e.deviantart.com/emoticons/s/shakefist.gif

РЕДАКТИРОВАТЬ: Я вижу, никто не хочет мне помочь. Может быть, это потому, что это д-р. Я постараюсь сократить его

некоторый код:

def ExtHandler(self, widget, url): # sorts out what to do with each file extensions
    name = url.split('/')[-1].split('?')[0]
    path = './Storage/Temp/Images/'+name
    try:
        if name.endswith('.gif'):
            img = Image.open(path)
            animation = []
            x = 0
            print name
            while True:
                try:
                    img.seek(x)

                    newpath = './Storage/Temp/Images/{0}__{1}.png'.format(x, name.split('.', 1)[0])
                    img.save(newpath, transparency = img.info['transparency'], format='PNG')

                    newimg = Image.open(path)
                    newimg.load()
                    newimg = newimg.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)

                    dur = img.info['duration']
                    if dur < 50: dur = 50
                    newimg = Image.open(newpath)

                    animation.append((PhotoImage2(newimg), dur))
                    x += 1
                except EOFError:
                    break #no more images in the animation!
                except Exception as e:
                    print traceback.format_exc()
                    break
            if len(animation) > 1:
                self.animations[name] = animation

        elif name.endswith('.jpg'):
            img = Image.open(path)
            img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)

        elif name.endswith('.png'):
            img = Image.open(path)
            img.load()
            try:
                alpha = img.split()[3]
                img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
                mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
                img.paste(255, mask)
            except:
                img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)

        height, width = img.size[0], img.size[1]
        if width > 100 or height > 100:
            img = maxSize(img, (100, 100), Image.ANTIALIAS) # resize thumbnails

        self.images[name] = PhotoImage2(img)
        if name in self.animations:
            self.animation(name)
        else:
            self.update_frames(name, self.images[name])
    except:
        print name
        traceback.print_exc()

def animation(self, name):
    if name not in self.animations:
        return
    x = self.animations[name].pop(0)
    self.animations[name].append(x)
    img, time = x

    self.images[name] = img
    self.update_frames(name, self.images[name])
    self.root.after(time, lambda: self.animation(name))

Ответы [ 2 ]

0 голосов
/ 12 июля 2011

Это моя рабочая версия (для преобразования GIF-файлов в серию PNG):

import traceback
import Image

class Test:

    def __init__(self):
        self.ExtHandler("", "http://fc02.deviantart.net/fs42/f/2009/061/d/8/d856ba6223c66ce347c6c814f67d307b.gif")
        self.ExtHandler("", "http://fc02.deviantart.net/fs70/f/2010/007/c/3/_mekolai__by_Pyritie.gif")
        self.ExtHandler("", "http://e.deviantart.com/emoticons/s/shakefist.gif")

    def ExtHandler(self, widget, url): # sorts out what to do with each file extensions
        name = url.split('/')[-1].split('?')[0]
        path = 'C:\\Temp\\'+name
        try:
            if name.endswith('.gif'):
                img = Image.open(path)
                print name
                while True:
                    try:
                        x = img.tell() + 1
                        img.seek(x)

                        newpath = 'C:\\Temp\\{1}_{0}.png'.format(x, name.split('.', 1)[0])
                        img.save(newpath, transparency = img.info['transparency'])
                    except EOFError:
                        break #no more images in the animation!
                    except Exception as e:
                        print traceback.format_exc()
                        break

            elif name.endswith('.jpg'):
                img = Image.open(path)
                img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)

            elif name.endswith('.png'):
                img = Image.open(path)
                img.load()
                try:
                    alpha = img.split()[3]
                    img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
                    mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
                    img.paste(255, mask)
                except:
                    img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
        except:
            print name
            traceback.print_exc()

Test()

Я думаю, что решение состоит в следующем:) поиск с img.tell () + 1 b) сохранение безпараметр формата

В вашем реальном коде вам, вероятно, не нужно кэшировать GIF-кадры как pngs.Просто ищите с img.tell () + 1:)

0 голосов
/ 12 июля 2011

Интересно .. Я вижу их всех оживленными.

Я включил ваши ссылки в этот ответ, чтобы людям не приходилось нажимать на ваши ссылки для просмотра анимации.

Works

Works

enter image description here

Обратите внимание, что я использую Chrome в качестве браузера.Я сохраню это сообщение и посмотрю, как оно выглядит в Internet Explorer и FireFox, и сообщу о результатах.

...

update

Хорошо, вот результаты:

Я на Windows XP.

  • Работает с IE8
  • Работает с Chrome 10.0.648.205
  • Работает с Chrome 14.0.810.0
  • Работает с FireFox 5.0

Итак, я не могу воспроизвести вашу проблему здесь.Я думаю, что вполне безопасно предположить, что эти анимации будут работать так, как ожидается в браузерах людей.

Возможно, вам следует добавить больше информации о том, как вы просматриваете анимацию.

С технической точки зрения я не вижу проблем, но анимации выглядят довольно дешево, поэтому яподумаю дважды, прежде чем добавлять их на сайт, но это дело вкуса.

update 2 Ах, я перечитал ваш вопрос.Вы не используете браузер, но вы создаете приложение.Я уверен, что проблема заключается в библиотеках, которые вы используете.

Может быть, вы можете открыть GIF-файл в чем-то вроде семинара по анимации Gif или в какой-нибудь подобной программе, чтобы увидеть разницу ... может быть, вы можете повторноспасти их таким образом, чтобы они все работали?

Это все, что я могу сказать, чтобы помочь тебе сейчас, я боюсь.

...