Last active
September 26, 2023 17:59
-
-
Save s-m-e/821f23a76ff03186d2c90797bcfe05d8 to your computer and use it in GitHub Desktop.
A simple script for generating individual frames of an animation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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