Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
107 changes: 107 additions & 0 deletions examples/video_generate_only_workflow/background_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from PIL import Image, ImageDraw, ImageFont
import textwrap
import os
import time
import uuid
import matplotlib.font_manager as fm

class BackgroundImageGenerator:
def __init__(self, topic=None):
self.width = 1920
self.height = 1080
self.background_color = (255, 255, 255)
self.title_color = (0, 0, 0)
self.topic = topic

self.config = {
'title_font_size': 50,
'subtitle_font_size': 54,
'title_max_width': 15,
'subtitle_color': (0, 0, 0),
'line_spacing': 15,
'output_dir': 'output',
'padding': 50,
'line_width': 8,
'subtitle_offset': 40,
'line_position_offset': 190
}
# 创建基础输出目录
os.makedirs(self.config['output_dir'], exist_ok=True)
# 如果有主题,创建主题目录
if self.topic:
self.theme_dir = os.path.join(self.config['output_dir'], self.topic)
os.makedirs(self.theme_dir, exist_ok=True)

def _get_font(self, size):
script_dir = os.path.dirname(os.path.abspath(__file__))
font_names = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC', 'Microsoft YaHei']
# 首先尝试加载本地字体文件
local_font = os.path.join(script_dir, 'asset', '字小魂扶摇手书(商用需授权).ttf')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

字体文件 字小魂扶摇手书(商用需授权).ttf 的文件名暗示其商用需要授权。在开源项目中使用此字体可能存在法律风险。请确认该字体的许可证是否与项目兼容,或者替换为明确的开源字体。

try:
return ImageFont.truetype(local_font, size)
except Exception as e:
print(f"本地字体加载失败: {local_font}, 错误: {str(e)}")
# 尝试使用matplotlib查找系统中的中文字体
for font_name in font_names:
try:
font_path = fm.findfont(fm.FontProperties(family=font_name))
return ImageFont.truetype(font_path, size)
except Exception as e:
print(f"无法找到字体: {font_name}, 错误: {str(e)}")
continue

print("所有字体加载失败,使用默认字体")
return ImageFont.load_default()

def generate(self, title_text, **kwargs):
config = {**self.config, **kwargs}
image = Image.new('RGB', (self.width, self.height), kwargs.get('bg_color', self.background_color))
draw = ImageDraw.Draw(image)

title_font = self._get_font(config['title_font_size'])
subtitle_font = self._get_font(config['subtitle_font_size'])

title_lines = textwrap.wrap(title_text, width=config['title_max_width'])
y_position = config['padding']
for line in title_lines:
bbox = draw.textbbox((0, 0), line, font=title_font)
draw.text(
(config['padding'], y_position),
line,
font=title_font,
fill=kwargs.get('title_color', self.title_color)
)
y_position += (bbox[3] - bbox[1]) + config['line_spacing']

if config.get('subtitle_lines'):
y_position = config['padding']
for i, line in enumerate(config['subtitle_lines']):
bbox = draw.textbbox((0, 0), line, font=subtitle_font)
x_offset = self.width - bbox[2] - (config['padding'] + 30) + (i * config['subtitle_offset'])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

在计算字幕的 x_offset 时,使用了一个魔法数字 30。为了提高代码的可读性和可维护性,建议将其提取到 self.config 字典中,并赋予一个有意义的名称,例如 subtitle_right_margin

draw.text(
(x_offset, y_position),
line,
font=subtitle_font,
fill=config['subtitle_color']
)
y_position += bbox[3] - bbox[1] + 5

line_y = self.height - config['padding'] - config['line_position_offset']
draw.line([
(0, line_y),
(self.width, line_y)
], fill=(0, 0, 0), width=config['line_width'])

# 生成输出路径
if self.topic:
output_dir = os.path.join(config['output_dir'], self.topic)
os.makedirs(output_dir, exist_ok=True)
else:
output_dir = config['output_dir']
Comment on lines +96 to +

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

此处的目录创建逻辑与 __init__ 方法中的部分逻辑重复,并且存在不一致性。当 self.topicFalse 时,没有为 output_dir 调用 os.makedirs,这依赖于 __init__ 中的创建。建议将目录创建逻辑统一,以提高代码的清晰度和健壮性。

Suggested change
if self.topic:
output_dir = os.path.join(config['output_dir'], self.topic)
os.makedirs(output_dir, exist_ok=True)
else:
output_dir = config['output_dir']
if self.topic:
output_dir = os.path.join(config['output_dir'], self.topic)
os.makedirs(output_dir, exist_ok=True)
else:
output_dir = config['output_dir']
os.makedirs(output_dir, exist_ok=True)


output_path = os.path.join(
output_dir,
f'title_{uuid.uuid4()}.png'
)
image.save(output_path)
return output_path
Loading