Skip to content

Instantly share code, notes, and snippets.

@s-m-e
Last active September 26, 2023 17:59
Show Gist options
  • Save s-m-e/821f23a76ff03186d2c90797bcfe05d8 to your computer and use it in GitHub Desktop.
Save s-m-e/821f23a76ff03186d2c90797bcfe05d8 to your computer and use it in GitHub Desktop.
A simple script for generating individual frames of an animation
import cairo
import math
import os
class Image:
def __init__(self, width, height, background_color = (1.0, 1.0, 1.0)):
self._width, self._height = width, height
self._surface = cairo.ImageSurface(cairo.FORMAT_RGB24, self._width, self._height)
self._ctx = cairo.Context(self._surface)
self._set_background_color(background_color)
def save(self, fn):
self._surface.write_to_png(fn)
def draw_polygon(self,
*points,
**kwargs,
):
assert len(points) >= 2
self._ctx.move_to(*points[0])
for point in points[1:]:
self._ctx.line_to(*point)
self._ctx.close_path()
self._stroke(**kwargs)
def draw_circle(self,
x = 0.0, y = 0.0, r = 1.0,
**kwargs,
):
self._ctx.arc(
x, y, r,
0, 2 * math.pi, # 0 bis 360°
)
self._stroke(**kwargs)
def _stroke(self,
line_color = (1.0, 1.0, 1.0),
line_width = 1.0,
**kwargs,
):
self._ctx.set_source_rgb(*line_color)
self._ctx.set_line_width(line_width)
self._ctx.stroke()
def _set_background_color(self,
fill_color = (1.0, 1.0, 1.0),
):
self._ctx.set_source_rgb(*fill_color)
self._ctx.rectangle(0, 0, self._width, self._height)
self._ctx.fill()
fps = 120 # Frames per second
duration = 10 # Seconds total
frames = fps * duration
scale = 1 # scale factor for resolution. 1 for 1k, 2 for 4k
for frame in range(frames):
angle = frame * 2 * math.pi / frames
image = Image(1920 * scale, 1080 * scale)
image.draw_circle(
x = (1920 / 2 + 200 * math.sin(angle)) * scale,
y = (1080 / 2 + 200 * math.cos(angle)) * scale,
r = 100.0 * scale,
line_color = (1.0, 0.0, 0.0),
line_width = 2.0 * scale,
)
image.draw_polygon(
(
(1920 / 2 - 300) * scale, (1080 / 2 - 300) * scale
), (
(1920 / 2 + 300) * scale, (1080 / 2 + 300) * scale
),
line_color = (0.0, 0.0, 1.0),
line_width = 3.0 * scale,
)
image.save(os.path.join('images', f'frame_{frame:04d}.png'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment