Spaces:
Sleeping
Sleeping
File size: 3,505 Bytes
346533a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
from typing import List, Literal
from pil_utils import BuildImage
from pydantic import Field
from meme_generator import MemeArgsModel, MemeArgsParser, MemeArgsType, add_meme
from meme_generator.utils import (
FrameAlignPolicy,
Maker,
make_gif_or_combined_gif,
make_jpg_or_gif,
)
help = "生成模式"
parser = MemeArgsParser(prefix_chars="-/")
group = parser.add_mutually_exclusive_group()
group.add_argument(
"--mode",
type=str,
choices=["normal", "circle", "loop"],
default="normal",
help=help,
)
group.add_argument("--circle", "/套娃", action="store_const", const="circle", dest="mode")
group.add_argument("--loop", "/循环", action="store_const", const="loop", dest="mode")
class Model(MemeArgsModel):
mode: Literal["normal", "loop", "circle"] = Field("normal", description=help)
def always_normal(img: BuildImage):
def make(img: BuildImage) -> BuildImage:
img_big = img.convert("RGBA").resize_width(500)
img_small = img.convert("RGBA").resize_width(100)
h1 = img_big.height
h2 = max(img_small.height, 80)
frame = BuildImage.new("RGBA", (500, h1 + h2 + 10), "white")
frame.paste(img_big, alpha=True).paste(
img_small, (290, h1 + 5 + (h2 - img_small.height) // 2), alpha=True
)
frame.draw_text(
(20, h1 + 5, 280, h1 + h2 + 5), "要我一直", halign="right", max_fontsize=60
)
frame.draw_text(
(400, h1 + 5, 480, h1 + h2 + 5), "吗", halign="left", max_fontsize=60
)
return frame
return make_jpg_or_gif(img, make)
def always_always(img: BuildImage, loop: bool = False):
tmp_img = img.convert("RGBA").resize_width(500)
img_h = tmp_img.height
text_h = tmp_img.resize_width(100).height + tmp_img.resize_width(20).height + 10
text_h = max(text_h, 80)
frame_h = img_h + text_h
text_frame = BuildImage.new("RGBA", (500, frame_h), "white")
text_frame.draw_text(
(0, img_h, 280, frame_h), "要我一直", halign="right", max_fontsize=60
).draw_text((400, img_h, 500, frame_h), "吗", halign="left", max_fontsize=60)
frame_num = 20
coeff = 5 ** (1 / frame_num)
def maker(i: int) -> Maker:
def make(img: BuildImage) -> BuildImage:
img = img.convert("RGBA").resize_width(500)
base_frame = text_frame.copy().paste(img, alpha=True)
frame = BuildImage.new("RGBA", base_frame.size, "white")
r = coeff**i
for _ in range(4):
x = round(358 * (1 - r))
y = round(frame_h * (1 - r))
w = round(500 * r)
h = round(frame_h * r)
frame.paste(base_frame.resize((w, h)), (x, y))
r /= 5
return frame
return make
if not loop:
return make_jpg_or_gif(img, maker(0))
return make_gif_or_combined_gif(
img, maker, frame_num, 0.1, FrameAlignPolicy.extend_loop
)
def always(images: List[BuildImage], texts, args: Model):
img = images[0]
mode = args.mode
if mode == "normal":
return always_normal(img)
elif mode == "circle":
return always_always(img, loop=False)
else:
return always_always(img, loop=True)
add_meme(
"always",
always,
min_images=1,
max_images=1,
args_type=MemeArgsType(
parser, Model, [Model(mode="normal"), Model(mode="circle"), Model(mode="loop")]
),
keywords=["一直"],
)
|