|
| 1 | +import argparse |
| 2 | +import os |
| 3 | +from glob import glob |
| 4 | + |
| 5 | +from PIL import Image |
| 6 | + |
| 7 | +IMG_EXTENSIONS = ['jpg', 'jpeg', 'png'] # Supported Image Extensions |
| 8 | +OUTPUT_EXTENSIONS = ['gif', 'webp', 'png'] # Supported Animated Image Extensions |
| 9 | + |
| 10 | +# Argument parsing |
| 11 | +parser = argparse.ArgumentParser() |
| 12 | +parser.add_argument('--target', help='Target directory which contains frame images.') |
| 13 | +parser.add_argument('--output_extension', default='gif', |
| 14 | + help='Output file extension. GIF(default), WEBP or APNG(animated png).') |
| 15 | +parser.add_argument('--speed', default=25, type=int, help='Milliseconds per frame. Smaller means faster.') |
| 16 | +parser.add_argument('--output', default=None, help='Output file name. This overrides `format` argument.') |
| 17 | + |
| 18 | +args = parser.parse_args() # parse all args. |
| 19 | + |
| 20 | +# Find all valid image files. |
| 21 | +frames = [] |
| 22 | +for ext in IMG_EXTENSIONS: |
| 23 | + frames.extend(glob(os.path.join(args.target, f'*.{ext}'))) |
| 24 | + |
| 25 | +# Open all images |
| 26 | +frames = [Image.open(path).convert('RGB') for path in frames] |
| 27 | +print(f'{len(frames)} files found') |
| 28 | + |
| 29 | +# Save as an animation |
| 30 | +output_path = os.path.join(args.target, f"result.{args.output_extension}") |
| 31 | +if args.output is not None: |
| 32 | + output_path = args.output |
| 33 | + |
| 34 | + |
| 35 | +frames[0].save(output_path, save_all=True, append_images=frames[1:], loop=0, |
| 36 | + duration=args.speed) |
| 37 | +print(f'Save success for {output_path}') |
0 commit comments