Итерация кадров GIF - PullRequest
1 голос
/ 26 мая 2020

Я пытаюсь извлечь все кадры из файла gif в список с помощью PIL , чтобы выполнить с ними другие операции.

from PIL import Image

im = Image.open(r'C:\Users\Jakub\Documents\test.gif')

frames = []
for x in range(0, im.n_frames):
    im.seek(x)  # `im.seek(im.tell()+1)` returns None
    frames.append(im)

frames # returns [Image1, Image1, Image1, ...]

Как я могу этого добиться результат:

...
>>> frames
[Image1, Image2, Image3, ...]

1 Ответ

0 голосов
/ 22 июня 2020

Вы можете попробовать мою библиотеку GIF :

from PIL import Image

def GIF_Load(file):
    from platform import system
    from ctypes import string_at, Structure, c_long as cl, c_ubyte, \
                       py_object, pointer, POINTER as PT, CFUNCTYPE, CDLL
    class GIF_WHDR(Structure): _fields_ = \
       [("xdim", cl), ("ydim", cl), ("clrs", cl), ("bkgd", cl),
        ("tran", cl), ("intr", cl), ("mode", cl), ("frxd", cl), ("fryd", cl),
        ("frxo", cl), ("fryo", cl), ("time", cl), ("ifrm", cl), ("nfrm", cl),
        ("bptr", PT(c_ubyte)), ("cpal", PT(c_ubyte))]
    def intr(y, x, w, base, tran): base.paste(tran.crop((0, y, x, y + 1)), w)
    def skew(i, r): return r >> ((7 - (i & 2)) >> (1 + (i & 1)))
    def fill(w, d, p):
        retn = Image.new("L", d, w.bkgd) if (w.tran < 0) else \
               Image.new("RGBA", d)
        if (w.tran < 0):
            retn.putpalette(p)
        return retn
    def WriteFunc(d, w):
        cpal = string_at(w[0].cpal, w[0].clrs * 3)
        list = d.contents.value[0]
        if (len(list) == 0):
            list.append(Image.new("RGBA", (w[0].xdim, w[0].ydim)))
        tail = len(list) - 1
        base = Image.frombytes("L", (w[0].frxd, w[0].fryd),
                               string_at(w[0].bptr, w[0].frxd * w[0].fryd))
        if (w[0].intr != 0):
            tran = base.copy()
            [intr(skew(y, y) + (skew(y, w[0].fryd - 1) + 1, 0)[(y & 7) == 0],
                  w[0].frxd, (0, y), base, tran) for y in range(w[0].fryd)]
        tran = Image.eval(base, lambda indx: (255, 0)[indx == w[0].tran])
        base.putpalette(cpal)
        list[tail].paste(base, (w[0].frxo, w[0].fryo), tran)
        list[tail].info = {"delay" : w[0].time}
        if (w[0].ifrm != (w[0].nfrm - 1)):
            trgt = (tail, d.contents.value[1])[w[0].mode == 3]
            list.append(list[trgt].copy() if (trgt >= 0) else
                        fill(w[0], (w[0].xdim, w[0].ydim), cpal))
            if (w[0].mode != 3):
                d.contents.value[1] = w[0].ifrm
            if (w[0].mode == 2):
                list[tail + 1].paste(fill(w[0], (w[0].frxd, w[0].fryd), cpal),
                                                (w[0].frxo, w[0].fryo))
    try: file = open(file, "rb")
    except IOError: return []
    file.seek(0, 2)
    size = file.tell()
    file.seek(0, 0)
    list = [[], -1]
    CDLL(("%s.so", "%s.dll")[system() == "Windows"] % "./gif_load"). \
    GIF_Load(file.read(), size,
             CFUNCTYPE(None, PT(py_object), PT(GIF_WHDR))(WriteFunc),
             None, pointer(py_object(list)), 0)
    file.close()
    return list[0]
...