Skip to content

Commit

Permalink
Improved text rendering size calculation to make text fill more of th…
Browse files Browse the repository at this point in the history
…e region bounding box areas
  • Loading branch information
beveradb committed Dec 28, 2024
1 parent fc5eabb commit ee9958b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 73 deletions.
30 changes: 23 additions & 7 deletions karaoke_prep/karaoke_prep.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,10 @@ def _render_text_in_region(self, draw, text, font_path, region, color, gradient=
self.logger.debug("Text is None, skipping rendering")
return region

if region is None:
self.logger.debug("Region is None, skipping rendering")
return region

if font is None:
font, text_lines = self.calculate_text_size_to_fit(draw, text, font_path, region)
else:
Expand All @@ -673,6 +677,9 @@ def _render_text_in_region(self, draw, text, font_path, region, color, gradient=
font_height = ascent + descent

def render_text_with_gradient(text, position, bbox):
# Convert position coordinates to integers
position = (int(position[0]), int(position[1]))

if gradient is None:
draw.text(position, text, fill=color, font=font)
else:
Expand Down Expand Up @@ -702,20 +709,25 @@ def render_text_with_gradient(text, position, bbox):
bbox1 = draw.textbbox((0, 0), line1, font=font)
bbox2 = draw.textbbox((0, 0), line2, font=font)

# Calculate positions using font metrics
total_height = font_height * 2 # Height for both lines
line_gap = font_height * 0.1 # 10% of font height for gap
total_space = total_height + line_gap
# Calculate line heights using bounding boxes
line1_height = bbox1[3] - bbox1[1]
line2_height = bbox2[3] - bbox2[1]

# Center the entire text block vertically
y_start = y + (height - total_space) // 2
# Use a small gap between lines (20% of average line height)
line_gap = int((line1_height + line2_height) * 0.1)

# Calculate total height needed
total_height = line1_height + line_gap + line2_height

# Center the entire text block vertically in the region
y_start = y + (height - total_height) // 2

# Draw first line
pos1 = (x + (width - bbox1[2]) // 2, y_start)
render_text_with_gradient(line1, pos1, bbox1)

# Draw second line
pos2 = (x + (width - bbox2[2]) // 2, y_start + font_height + line_gap)
pos2 = (x + (width - bbox2[2]) // 2, y_start + line1_height + line_gap)
render_text_with_gradient(line2, pos2, bbox2)
else:
# Single line
Expand All @@ -731,6 +743,10 @@ def render_text_with_gradient(text, position, bbox):

def _draw_bounding_box(self, draw, region, color):
"""Helper method to draw a bounding box around a region."""
if region is None:
self.logger.debug("Region is None, skipping drawing bounding box")
return

x, y, width, height = region
draw.rectangle([x, y, x + width, y + height], outline=color, width=2)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "karaoke-prep"
version = "0.34.0"
version = "0.34.1"
description = "Prepare for karaoke video creation, by downloading audio and lyrics for a specified song or playlist from youtube and separating audio stems. After syncing, finalise the video with a title screen!"
authors = ["Andrew Beveridge <[email protected]>"]
license = "MIT"
Expand Down
82 changes: 17 additions & 65 deletions tests/test_create_intro_end_screens.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#! /usr/bin/env python3

import os
import json
import logging
Expand All @@ -23,57 +25,21 @@ def total_length(tuple):

# Sort by length and get shortest and longest 20
sorted_combinations = sorted(all_combinations, key=total_length)
artist_title_combinations = sorted_combinations[:10] + sorted_combinations[-10:]
artist_title_combinations = sorted_combinations[:20] + sorted_combinations[-20:]

# Define the format dictionary with expanded configurations
formats = [
{
"name": "vocalstar",
"intro_background_image": "/Users/andrew/AB Dropbox/Andrew Beveridge/MediaUnsynced/Karaoke/Tracks-NonPublished/VocalStar/Resources/vocal-star-title-background-black.4k.png",
"end_background_image": "/Users/andrew/AB Dropbox/Andrew Beveridge/MediaUnsynced/Karaoke/Tracks-NonPublished/VocalStar/Resources/vocal-star-end-card-black.4k.png",
"font": "Zurich_Cn_BT_Bold.ttf",
"artist_color": "#FCDF01",
"title_color": "#FCDF01",
"intro_title_region": "370,470,3100,480",
"intro_artist_region": "370,1210,3100,480",
"intro_extra_text": "GET READY TO SING!",
"intro_extra_text_color": "#FFFFFF",
"intro_extra_text_region": "370,1800,3100,280",
"end_title_region": "370,670,3100,480",
"end_artist_region": "370,1410,3100,480",
"end_extra_text": "THANK YOU FOR SINGING!",
"end_extra_text_color": "#FFFFFF",
"end_extra_text_region": "370,1800,3100,280",
"name": "nomadkaraoke",
"style_params_json": "/Users/andrew/AB Dropbox/Andrew Beveridge/MediaUnsynced/Karaoke/NomadBranding/karaoke-prep-styles-nomad.json",
},
{
"name": "nomadkaraoke",
"intro_background_image": "/Users/andrew/AB Dropbox/Andrew Beveridge/MediaUnsynced/Karaoke/NomadBranding/karaoke-title-screen-background-nomad-4k.png",
"end_background_color": "#000000", # Using solid color for end screen
"font": "AvenirNext-Bold.ttf",
"artist_color": "#FFFFFF",
"title_color": "#ffdf6b",
"intro_title_region": "370,950,3100,350",
"intro_artist_region": "370,1350,3100,450",
"intro_extra_text": None, # No extra text on intro
"end_title_region": "370,800,3100,350",
"end_artist_region": "370,1200,3100,450",
"end_extra_text": "Follow us @NomadKaraoke",
"end_extra_text_color": "#ffdf6b",
"end_extra_text_region": "370,1700,3100,280",
"name": "vocalstar",
"style_params_json": "/Users/andrew/AB Dropbox/Andrew Beveridge/MediaUnsynced/Karaoke/Tracks-NonPublished/VocalStar/Resources/karaoke-prep-styles-vocalstar.json",
},
{
"name": "minimal",
"intro_background_color": "#000033",
"end_background_color": "#000033",
"font": "Montserrat-Bold.ttf",
"artist_color": "#FFFFFF",
"title_color": "#ffdf6b",
"intro_title_region": "370,800,3100,400",
"intro_artist_region": "370,1300,3100,400",
"intro_extra_text": None, # No extra text on either screen
"end_title_region": "370,800,3100,400",
"end_artist_region": "370,1300,3100,400",
"end_extra_text": None,
"style_params_json": None,
},
]

Expand All @@ -87,34 +53,18 @@ def total_length(tuple):
format_output_dir = os.path.join(base_output_dir, format["name"])
os.makedirs(format_output_dir, exist_ok=True)

style_params = None
if format["style_params_json"]:
with open(format["style_params_json"], "r") as f:
style_params = json.loads(f.read())

# Instantiate KaraokePrep for this format
kprep = KaraokePrep(
log_level=logging.INFO,
log_formatter=log_formatter,
output_dir=format_output_dir,
intro_background_image=format.get("intro_background_image"),
intro_background_color=format.get("intro_background_color", "#000000"),
end_background_image=format.get("end_background_image"),
end_background_color=format.get("end_background_color", "#000000"),
intro_font=format["font"],
end_font=format["font"],
intro_artist_color=format["artist_color"],
intro_title_color=format["title_color"],
end_artist_color=format["artist_color"],
end_title_color=format["title_color"],
intro_title_region=format.get("intro_title_region"),
intro_artist_region=format.get("intro_artist_region"),
intro_extra_text=format.get("intro_extra_text"),
intro_extra_text_color=format.get("intro_extra_text_color"),
intro_extra_text_region=format.get("intro_extra_text_region"),
end_title_region=format.get("end_title_region"),
end_artist_region=format.get("end_artist_region"),
end_extra_text=format.get("end_extra_text"),
end_extra_text_color=format.get("end_extra_text_color"),
end_extra_text_region=format.get("end_extra_text_region"),
intro_video_duration=0,
end_video_duration=0,
render_bounding_boxes=True,
style_params=style_params,
render_bounding_boxes=False,
output_jpg=False,
output_png=True,
)
Expand All @@ -128,6 +78,7 @@ def total_length(tuple):
title_image_filepath_noext = os.path.join(format_output_dir, f"{sanitized_artist}_{sanitized_title}_title")
title_video_filepath = os.path.join(format_output_dir, f"{sanitized_artist}_{sanitized_title}_title.mov")

kprep.intro_video_duration = 0
kprep.create_title_video(
artist=artist,
title=title,
Expand All @@ -141,6 +92,7 @@ def total_length(tuple):
end_image_filepath_noext = os.path.join(format_output_dir, f"{sanitized_artist}_{sanitized_title}_end")
end_video_filepath = os.path.join(format_output_dir, f"{sanitized_artist}_{sanitized_title}_end.mov")

kprep.end_video_duration = 0
kprep.create_end_video(
artist=artist,
title=title,
Expand Down

0 comments on commit ee9958b

Please sign in to comment.