77 lines
2.8 KiB
Python
77 lines
2.8 KiB
Python
import os
|
|
import requests
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
import textwrap
|
|
|
|
FONT_DIR = "assets/fonts"
|
|
FONT_PATH = os.path.join(FONT_DIR, "Roboto-Bold.ttf")
|
|
BODY_FONT_PATH = os.path.join(FONT_DIR, "Roboto-Regular.ttf")
|
|
|
|
def download_fonts():
|
|
"""Downloads Roboto font if not present."""
|
|
if not os.path.exists(FONT_DIR):
|
|
os.makedirs(FONT_DIR)
|
|
|
|
fonts = {
|
|
"Roboto-Bold.ttf": "https://github.com/google/fonts/raw/main/apache/roboto/Roboto-Bold.ttf",
|
|
"Roboto-Regular.ttf": "https://github.com/google/fonts/raw/main/apache/roboto/Roboto-Regular.ttf"
|
|
}
|
|
|
|
for name, url in fonts.items():
|
|
path = os.path.join(FONT_DIR, name)
|
|
if not os.path.exists(path):
|
|
try:
|
|
print(f"Downloading {name}...")
|
|
response = requests.get(url)
|
|
if response.status_code == 200:
|
|
with open(path, "wb") as f:
|
|
f.write(response.content)
|
|
except Exception as e:
|
|
print(f"Failed to download font {name}: {e}")
|
|
|
|
def format_slide(slide_image: Image.Image, slide_number: int, total_slides: int, style_config: dict) -> Image.Image:
|
|
"""
|
|
Formats the AI-generated slide (with text) by adding a subtle footer for navigation.
|
|
"""
|
|
# Ensure fonts are available (for footer)
|
|
if not os.path.exists(FONT_PATH):
|
|
download_fonts()
|
|
|
|
target_size = (1080, 1350)
|
|
img = slide_image.resize(target_size, Image.Resampling.LANCZOS)
|
|
|
|
# We remove the heavy overlay because the AI image already has text and design integrated.
|
|
# A very subtle gradient at the bottom might be nice for the footer, but let's keep it minimal.
|
|
|
|
draw = ImageDraw.Draw(img)
|
|
|
|
# Load Fonts (only for footer)
|
|
try:
|
|
footer_font = ImageFont.truetype(BODY_FONT_PATH, 30)
|
|
except:
|
|
footer_font = ImageFont.load_default()
|
|
|
|
text_color = style_config["text_color"]
|
|
margin = 80
|
|
|
|
# Footer (Slide Number)
|
|
footer_text = f"{slide_number} / {total_slides}"
|
|
bbox = draw.textbbox((0, 0), footer_text, font=footer_font)
|
|
|
|
# Draw a small background for readability if needed, or just text
|
|
# Let's draw text with a slight shadow or outline for readability on varied backgrounds
|
|
x = target_size[0] - bbox[2] - margin
|
|
y = target_size[1] - 80
|
|
|
|
# Simple shadow
|
|
shadow_color = (0, 0, 0) if sum(text_color) > 300 else (255, 255, 255)
|
|
draw.text((x+2, y+2), footer_text, font=footer_font, fill=shadow_color)
|
|
draw.text((x, y), footer_text, font=footer_font, fill=text_color)
|
|
|
|
# Branding (Optional) - REMOVED
|
|
# branding = "Generated by Gemini"
|
|
# draw.text((margin+2, y+2), branding, font=footer_font, fill=shadow_color)
|
|
# draw.text((margin, y), branding, font=footer_font, fill=text_color)
|
|
|
|
return img
|