I need to generate an easy animation video in Python (I use PIL to create every frame, then combine them using
avconv). The animation is just an image being zoomed out.
That's my code:
for i in xrange(zoom_length): # zoom level on this step zoom = 1.0 - 1.0 * i * (max_zoom / zoom_length) # "size" is the resulting video frame size # "img.size" is the source image size (around 2.5x bigger than the frame) anti_zoomed_frame_size = int(size / zoom), int(size / zoom) anti_zoomed_frame_margins = (img.size - anti_zoomed_frame_size) / 2, (img.size - anti_zoomed_frame_size) / 2 anti_zoomed_frame = img.crop(anti_zoomed_frame_margins + (anti_zoomed_frame_size + anti_zoomed_frame_margins, anti_zoomed_frame_size + anti_zoomed_frame_margins)) frame = anti_zoomed_frame.resize(size, resample=Image.BILINEAR) print i, img.size, anti_zoomed_frame_size, anti_zoomed_frame_margins # frame No for debugging draw = ImageDraw.Draw(frame) draw.text((size - 200, size - 100), str(i), (0,0,0), font=font) yield frame
So what happens is I crop out of the source image a rectangle of size
frame_size / zoom , then I resize it
zoom times to get the needed frame size.
zoom <= 1.0 so doing it in this order seems to be a good idea, though I also tried doing it the other way (resize, then crop).
Anyway in both cases the resulting video is kind of shaking at times. It seems that the problem is in rounding the numbers. The math I'm doing inevitably leads to non-integers, yet PIL requires integers everywhere (also the resulting frame size is obviously a pair of integer constants). This rounding operation seems to affect the smoothness of the animation badly.
How smooth zooming is implemented in real life?