Skip to content

Commit d96845e

Browse files
authored
add meme backflip (#274)
1 parent 00316d5 commit d96845e

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import math
2+
from datetime import datetime
3+
from pathlib import Path
4+
5+
from pil_utils import BuildImage
6+
7+
from meme_generator import add_meme
8+
from meme_generator.utils import FrameAlignPolicy, Maker, make_gif_or_combined_gif
9+
10+
img_dir = Path(__file__).parent / "images"
11+
12+
13+
def backflip(images: list[BuildImage], texts, args):
14+
img_w, img_h = images[0].size
15+
length = math.sqrt(img_w * img_w + img_h * img_h)
16+
frame_w = int(length * 1.3)
17+
bounce_h = img_h * 1.2
18+
frame_h = int(bounce_h + length / 2 + img_h * 0.6)
19+
center_x = frame_w / 2
20+
ground_y = frame_h - img_h / 2
21+
22+
total_frames = 30
23+
bounce1_range = (0.0, 0.3)
24+
bounce2_range = (0.3, 0.6)
25+
rise_range = (0.6, 0.65)
26+
flip_range = (0.65, 0.95)
27+
land_range = (0.95, 1.0)
28+
29+
def maker(i: int) -> Maker:
30+
def make(imgs: list[BuildImage]) -> BuildImage:
31+
t = i / total_frames
32+
33+
if bounce1_range[0] <= t < bounce1_range[1]:
34+
local_t = (t - bounce1_range[0]) / (bounce1_range[1] - bounce1_range[0])
35+
y = -4 * bounce_h * (local_t - 0.5) ** 2 + bounce_h
36+
rot = 45 * (1 - 2 * abs(local_t - 0.5))
37+
elif bounce2_range[0] <= t < bounce2_range[1]:
38+
local_t = (t - bounce2_range[0]) / (bounce2_range[1] - bounce2_range[0])
39+
y = -4 * bounce_h * (local_t - 0.5) ** 2 + bounce_h
40+
rot = -45 * (1 - 2 * abs(local_t - 0.5))
41+
elif rise_range[0] <= t < rise_range[1]:
42+
local_t = (t - rise_range[0]) / (rise_range[1] - rise_range[0])
43+
y = bounce_h - bounce_h * (1 - local_t) ** 2
44+
rot = 0.0
45+
elif flip_range[0] <= t < flip_range[1]:
46+
local_t = (t - flip_range[0]) / (flip_range[1] - flip_range[0])
47+
y = bounce_h
48+
rot = 360 * local_t
49+
elif land_range[0] <= t < land_range[1]:
50+
local_t = (t - land_range[0]) / (land_range[1] - land_range[0])
51+
y = bounce_h - bounce_h * local_t**2
52+
rot = 0.0
53+
else:
54+
y = ground_y
55+
rot = 0.0
56+
57+
frame = BuildImage.new("RGBA", (frame_w, frame_h))
58+
img = imgs[0].convert("RGBA").rotate(-rot, expand=True)
59+
frame.paste(
60+
img,
61+
(int(center_x - img.width / 2), int(ground_y - y - img.height / 2)),
62+
alpha=True,
63+
)
64+
return frame
65+
66+
return make
67+
68+
return make_gif_or_combined_gif(
69+
images, maker, total_frames, 0.05, FrameAlignPolicy.extend_loop
70+
)
71+
72+
73+
add_meme(
74+
"backflip",
75+
backflip,
76+
min_images=1,
77+
max_images=1,
78+
keywords=["后空翻"],
79+
date_created=datetime(2025, 6, 29),
80+
date_modified=datetime(2025, 6, 29),
81+
)

0 commit comments

Comments
 (0)