I have collected a large-scale datasets of gifs(more than 100k) from the Internet, and I meet some rare strange GIFs when I try to extract frames of GIFs with python. Three common used packages(moviepy
, PIL
, imageio
) provide totally different results of such rare strange gifs.
moviepy>=1.0.3
will block inVideoFileClip.iter_frames()
loop at the second frame forever, and the code won't throw an exception.
from moviepy.video.io.VideoFileClip import VideoFileClip
video = VideoFileClip(path)
frame_iterator = video.iter_frames()
PIL>=7.1.2
will output multiple frames as same as the first frame.
from PIL import Image, ImageSequence
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
video = Image.open(path)
frame_iterator = ImageSequence.Iterator(video)
imageio>=2.6.1
can extract the frames correctly while the output frames are strange.
import imageio
frame_iterator = imageio.get_reader(path)
Then you can dump the frames from frame_iterator
provided by these packages above:
def dump_video_frames(video_frames):
root = 'data/frames'
if os.path.exists(root):
shutil.rmtree(root)
os.makedirs(root)
for i, frame in enumerate(video_frames):
frame.save(os.path.join(root, '%d.jpg' % i))
frames = []
for frame in frame_iterator:
if isinstance(frame, np.ndarray):
frame = Image.fromarray(np.uint8(frame))
frames.append(frame.convert('RGB'))
dump_video_frames(frames)
Here is an example:
Original GIF:
The output of PIL
:
The output of imageio
:
You can see PIL
only get the first frame without any black area which is quite different with the output of imageio
.
So my question is how to detect such a strange gif in python? Since I use moviepy
first for its good performance in other gifs, I need to detect such a kind of GIF before the code use moviepy
to extract its frames in order to avoid the infinite loop in VideoFileClip.iter_frames()
which won't throw any exception. I can't get any information about such a rare gif from Google.
I will provide 2 more example GIFs below: