Merge pull request #62 from outis1one/clDemoe/add-moon-image-locations-ACdGH

Fix UnicodeEncodeError in caption drawing
This commit is contained in:
Outis
2026-05-01 14:08:41 -04:00
committed by GitHub
+35 -4
View File
@@ -36,7 +36,7 @@ from datetime import datetime, timezone
from pathlib import Path
import numpy as np
from PIL import Image, ImageDraw, ImageFilter
from PIL import Image, ImageDraw, ImageFilter, ImageFont
# Pillow ≥ 10 renamed resampling constants
try:
@@ -46,6 +46,39 @@ except AttributeError: # Pillow < 10
LANCZOS = Image.LANCZOS
BICUBIC = Image.BICUBIC
# Common DejaVu Sans paths across distros; first hit wins.
_DEJAVU_CANDIDATES = [
'/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',
'/usr/share/fonts/dejavu/DejaVuSans.ttf',
'/usr/share/fonts/TTF/DejaVuSans.ttf',
'/Library/Fonts/DejaVuSans.ttf', # macOS homebrew
]
def _load_font(size: int = 18) -> ImageFont.ImageFont:
"""Return a Unicode-capable font at `size` pt, or the PIL default."""
for path in _DEJAVU_CANDIDATES:
try:
return ImageFont.truetype(path, size)
except (OSError, IOError):
pass
return ImageFont.load_default()
def _draw_caption(draw: ImageDraw.ImageDraw, caption: str,
xy: tuple[int, int], output_w: int) -> None:
"""Draw a drop-shadow caption, sanitising characters the default font
cannot encode when no TTF is available."""
font = _load_font(max(14, output_w // 100))
# If we fell back to the bitmap default font it only handles latin-1; strip
# anything outside that range rather than crashing.
if not hasattr(font, 'path'):
caption = caption.encode('latin-1', errors='replace').decode('latin-1')
caption = caption.replace('\x3f', '-') # '?' placeholder → dash
x, y = xy
draw.text((x + 2, y + 2), caption, fill=(0, 0, 0), font=font)
draw.text((x, y), caption, fill=(220, 220, 220), font=font)
def _square_crop_to_disk(ref: Image.Image, threshold: int = 25) -> Image.Image:
"""Tight-crop a reference moon image to the disk's bounding square.
@@ -200,9 +233,7 @@ def composite_full_moon(
# ── Caption ──
if caption:
draw = ImageDraw.Draw(bg)
# Drop shadow for legibility
draw.text((24, output_size[1] - 44), caption, fill=(0, 0, 0))
draw.text((22, output_size[1] - 46), caption, fill=(220, 220, 220))
_draw_caption(draw, caption, (22, output_size[1] - 48), output_size[0])
Path(out_path).parent.mkdir(parents=True, exist_ok=True)
bg.save(out_path, quality=92)