Ident taglines as overlay frames, and an optional thicker logo shadow
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,9 +2,10 @@
|
||||
# Frames from build_3d_ident.py into a finished ident: a soft start, then the channel's logo fading in over the end.
|
||||
# compose_ident.sh <frames folder> <logo png> <out.mp4> [overlay folder of over_%04d.png, drawn on top]
|
||||
# LOGO_SHADOW=0.8 lays a soft dark shadow under the logo, for scenes busy behind it.
|
||||
# LOGO_SHADOW_BOOST=2 (at most 2) thickens that shadow after blurring, for a logo over something bright in its own colour.
|
||||
LOGO="[1:v]scale=992:-1,format=rgba,fade=t=in:st=4.4:d=0.8:alpha=1[logo];[0:v]fade=t=in:st=0:d=0.3[scene];[scene][logo]overlay=x=(W-w)/2-110:y=(H-h)/2-30:shortest=1"
|
||||
if [ -n "$LOGO_SHADOW" ]; then
|
||||
LOGO="[1:v]scale=992:-1,format=rgba,fade=t=in:st=4.4:d=0.8:alpha=1,split[logo][under];[under]colorchannelmixer=rr=0:gg=0:bb=0:aa=$LOGO_SHADOW,boxblur=26:2[shadow];[0:v]fade=t=in:st=0:d=0.3[scene];[scene][shadow]overlay=x=(W-w)/2-110:y=(H-h)/2-30:shortest=1[dim];[dim][logo]overlay=x=(W-w)/2-110:y=(H-h)/2-30:shortest=1"
|
||||
LOGO="[1:v]scale=992:-1,format=rgba,fade=t=in:st=4.4:d=0.8:alpha=1,split[logo][under];[under]colorchannelmixer=rr=0:gg=0:bb=0:aa=$LOGO_SHADOW,boxblur=26:2${LOGO_SHADOW_BOOST:+,colorchannelmixer=aa=$LOGO_SHADOW_BOOST}[shadow];[0:v]fade=t=in:st=0:d=0.3[scene];[scene][shadow]overlay=x=(W-w)/2-110:y=(H-h)/2-30:shortest=1[dim];[dim][logo]overlay=x=(W-w)/2-110:y=(H-h)/2-30:shortest=1"
|
||||
fi
|
||||
if [ -n "$4" ]; then
|
||||
ffmpeg -nostdin -y -loglevel error -framerate 50 -i "$1/frame_%04d.png" -loop 1 -i "$2" -framerate 50 -i "$4/over_%04d.png" -filter_complex \
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
"""A channel's tagline under its logo, as overlay frames for compose_ident.sh, fading in just after the logo.
|
||||
tagline.py "<words>" <out folder> [x] [y] [size]
|
||||
"""
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from PIL import Image, ImageDraw, ImageFilter, ImageFont
|
||||
words, out = sys.argv[1].upper(), Path(sys.argv[2]); out.mkdir(parents=True, exist_ok=True)
|
||||
x, y, size = (int(a) for a in (sys.argv[3:6] + ['340', '462', '26'][len(sys.argv[3:6]):]))
|
||||
font = ImageFont.truetype(str(Path(__file__).parents[1] / 'network-fonts/barlow-semibold.ttf'), size)
|
||||
SS = 2
|
||||
def draw(alpha):
|
||||
big = Image.new('RGBA', (1280 * SS, 720 * SS))
|
||||
shadow = Image.new('RGBA', big.size)
|
||||
pen, sh, cx = ImageDraw.Draw(big), ImageDraw.Draw(shadow), x * SS
|
||||
for ch in words:
|
||||
sh.text((cx, y * SS), ch, font=font.font_variant(size=size * SS), fill=(0, 0, 0, int(220 * alpha)))
|
||||
pen.text((cx, y * SS), ch, font=font.font_variant(size=size * SS), fill=(236, 226, 250, int(255 * alpha)))
|
||||
cx += pen.textlength(ch, font=font.font_variant(size=size * SS)) + size * SS * .28
|
||||
shadow = shadow.filter(ImageFilter.GaussianBlur(8 * SS))
|
||||
shadow.alpha_composite(big)
|
||||
return shadow.resize((1280, 720), Image.LANCZOS)
|
||||
blank = Image.new('RGBA', (1280, 720))
|
||||
full = draw(1.0)
|
||||
for frame in range(1, 351):
|
||||
t = (frame - 1) / 50
|
||||
a = 0 if t < 5.2 else min(1, (t - 5.2) / .8)
|
||||
(blank if a == 0 else full if a == 1 else draw(a)).save(out / f'over_{frame:04d}.png')
|
||||
Reference in New Issue
Block a user