I am looking some kind method to get gif frames number. I am looking on Google, StackOverflow and any other sites and I find only rubbish! Someone know how to do it? I need only simple number of gif frames.
6 Answers
Which method are you using to load/manipulate the frame? Are you using PIL? If not, I suggest checking it out: Python Imaging Library and specifically the PIL gif page.
Now, assuming you are using PIL to read in the gif, it's a pretty simple matter to determine which frame you are looking at. seek will go to a specific frame and tell will return which frame you are looking at.
from PIL import Image
im = Image.open("animation.gif")
# To iterate through the entire gif
try:
while 1:
im.seek(im.tell()+1)
# do something to im
except EOFError:
pass # end of sequence
Otherwise, I believe you can only find the number of frames in the gif by seeking until an exception (EOFError) is raised.
Just parse the file, gifs are pretty simple:
class GIFError(Exception): pass
def get_gif_num_frames(filename):
frames = 0
with open(filename, 'rb') as f:
if f.read(6) not in ('GIF87a', 'GIF89a'):
raise GIFError('not a valid GIF file')
f.seek(4, 1)
def skip_color_table(flags):
if flags & 0x80: f.seek(3 << ((flags & 7) + 1), 1)
flags = ord(f.read(1))
f.seek(2, 1)
skip_color_table(flags)
while True:
block = f.read(1)
if block == ';': break
if block == '!': f.seek(1, 1)
elif block == ',':
frames += 1
f.seek(8, 1)
skip_color_table(ord(f.read(1)))
f.seek(1, 1)
else: raise GIFError('unknown block type')
while True:
l = ord(f.read(1))
if not l: break
f.seek(l, 1)
return frames
I was faced with the same problem recently and found the documentation on GIFs particularly lacking. Here's my solution using imageio's get_reader to read the bytes of an image (useful if you just fetched the image via HTTP, for example) which conveniently stores frames in numpy matrices:
import imageio
gif = imageio.get_reader(image_bytes, '.gif')
# Here's the number you're looking for
number_of_frames = len(gif)
for frame in gif:
# each frame is a numpy matrix
If you just need to open a file, use:
gif = imageio.get_reader('cat.gif')
Ok, 9 years maybe are a little too much time, but here is my answer
import tkinter as tk
from PIL import Image
def number_of_frames(gif):
"Prints and returns the number of frames of the gif"
print(gif.n_frames)
return gif.n_frames
def update(ind):
global root, label
frame = frames[ind]
ind += 1
if ind == frameCnt:
ind = 0
label.configure(image=frame)
root.after(100, update, ind)
file = Image.open("001.gif")
frameCnt = number_of_frames(file)
root = tk.Tk()
frames = [tk.PhotoImage( file='001.gif', format = f'gif -index {i}')
for i in range(frameCnt)]
label = tk.Label(root)
label.pack()
root.after(0, update, 0)
root.mainloop()
Here's some code that will get you a list with the duration value for each frame in the GIF:
from PIL import Image
gif_image = Image.open("animation.gif")
metadata = []
for i in range(gif_image.n_frames):
gif_image.seek(i)
duration = gif_image.info.get("duration", 0)
metadata.append(duration)
You can modify the above code to also capture other data from each frame such as background color index, transparency, or version. The info
dictionary on each frame looks like this:
{'version': b'GIF89a', 'background': 0, 'transparency': 100, 'duration': 70}
If you are using PIL (Python Imaging Library) you can use the n_frames
attribute of an image object.
See this answer.