Skip to content

Instantly share code, notes, and snippets.

@lambdan
Last active February 19, 2022 11:56
Show Gist options
  • Save lambdan/0b31af6181daa62d806d18a734d22690 to your computer and use it in GitHub Desktop.
Save lambdan/0b31af6181daa62d806d18a734d22690 to your computer and use it in GitHub Desktop.
Add custom captions, like subtitles, to images easily
# -*- coding: utf-8 -*-
# usage: caption.py image.jpg "The text"
# you can use a | to force a newline
# settings
strokew = 4 # outline width
stroke_color = "#101010" # outline color
font_color = "#f0f0f0" # ebeb0b=yellow, f0f0f0=white
font_name = "arial.ttf"
font_div = 14 # image height / this = font size
chars_per_line = 42 # according to Netflix: https://partnerhelp.netflixstudios.com/hc/en-us/articles/215274938-What-is-the-maximum-number-of-characters-per-line-allowed-in-Timed-Text-assets-
### end of settings
import re, sys, io, time, textwrap, os, datetime
from PIL import Image, ImageDraw, ImageFont
safe_chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789." # safe chars to use in filename
if len(sys.argv) < 3:
print("usage:\n\tcaption.py image.jpg \"The text\"")
print()
sys.exit(1)
def safe_filename(text):
string = []
for c in text:
if c in safe_chars:
string.append(c)
return "".join(string)
def make_frame_captioned(in_img, text, out):
# generate subtitle frame
image = Image.open(in_img)
im_w,im_h = image.size[0], image.size[1]
draw = ImageDraw.Draw(image)
fo = ImageFont.truetype(font_name, int(im_h/font_div))
w,h = draw.textsize(text, font=fo)
draw.text( ( ((im_w-w)/2), ((im_h-h)/1.15) ), text, fill=font_color, font=fo, stroke_width=strokew, stroke_fill=stroke_color)
image.save(out)
picture = sys.argv[1]
if not os.path.isfile(picture):
print("error: image not found:", picture)
sys.exit(1)
caption = " ".join(sys.argv[2:])
output = safe_filename(datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "_" + caption[0:50] + ".jpg")
caption = textwrap.fill(caption,chars_per_line)
caption = caption.replace("|","\n") # use a | to force newline
print(picture, "-->")
print(caption)
print("-->", output)
make_frame_captioned(picture,caption,output)
@lambdan
Copy link
Author

lambdan commented Feb 19, 2022

1645271111_this is an example of what this thing can do

@lambdan
Copy link
Author

lambdan commented Feb 19, 2022

20220219125548_works pretty good with lower resolution DVD video

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment