Skip to content

Instantly share code, notes, and snippets.

@Xevion
Created December 31, 2021 03:28
Show Gist options
  • Save Xevion/47e59b3e7c253995310163fc525a221a to your computer and use it in GitHub Desktop.
Save Xevion/47e59b3e7c253995310163fc525a221a to your computer and use it in GitHub Desktop.
import math
import shutil
from typing import List
import imageio
import os
from PIL import Image, ImageDraw
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
IMG_OUT_DIRECTORY = os.path.join(SCRIPT_DIR, 'gif')
IMG_TEMP_OUT_DIR = os.path.join(IMG_OUT_DIRECTORY, 'temp')
os.makedirs(IMG_TEMP_OUT_DIR, exist_ok=True)
IMG_TEMP_GLOB = os.path.join(IMG_TEMP_OUT_DIR, '*.png')
GIF_FINAL_PATH = os.path.join(IMG_OUT_DIRECTORY, 'radial_wipe.gif')
FRAMES: int = 25 # The number of frames used to complete a single loop.
DURATION: float = 0.5 # The number of seconds to complete a single loop of the image.
SIZE: int = 100 # The size in pixels of the output image.
SUPER_SAMPLE: float = 5.0 # Reduce jagged edges but rendering at a increased resolution and then resize with a Antialased method
LOOP: bool = True # Loop once or infinitely.
images: List[str] = []
for i in range(0, FRAMES):
w, h = SIZE, SIZE
wSuper, hSuper = math.floor(w * SUPER_SAMPLE), math.floor(h * SUPER_SAMPLE)
img = Image.new("RGB", (wSuper, hSuper))
imgA = ImageDraw.Draw(img)
shape = [(1, 1), (wSuper - 1, hSuper - 1)]
progress = i / (FRAMES - 1)
imgA.pieslice(shape, start=90, end=360 * progress + 90, fill="#9ad140")
img = img.resize((w, h), resample=Image.ANTIALIAS)
filename = f'{i}.png'
temp_output_path = os.path.join(IMG_TEMP_OUT_DIR, filename)
with open(temp_output_path, 'wb') as file:
img.save(file)
images.append(temp_output_path)
calculated_fps = len(images) / DURATION
if calculated_fps > 100.0:
print('Warning: GIF images are not designed to exceed 100 FPS.')
print('\tIncrease duration to a minimum of {dur:.2f}s or decrease frame count to a maximum of {count:.2f} frames to fit.'.format(
dur=FRAMES / 100, count=100 * DURATION
))
print(f'Creating GIF at {GIF_FINAL_PATH}')
print(f'{DURATION} seconds, {len(images)} frames, {calculated_fps} fps')
with imageio.get_writer(GIF_FINAL_PATH, mode='I', fps=calculated_fps, loop=0 if LOOP else 1) as writer:
for frame in images:
writer.append_data(imageio.imread(frame))
shutil.rmtree(IMG_TEMP_OUT_DIR)
print('{:.2f} kB written.'.format(
os.stat(GIF_FINAL_PATH).st_size / 1024
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment