from PIL import Image, ImageDraw, ImageFont
import random
import sys
import os
def generate_random_color():
"""生成一个随机颜色,避免白色(RGB值不全为255)。"""
while True:
color = tuple(random.randint(0, 255) for _ in range(3))
if color != (255, 255, 255):
return color
def generate_gradient(width, height, start_color, end_color, is_horizontal=True):
"""生成线性渐变背景。"""
base = Image.new('RGB', (width, height), start_color)
top = Image.new('RGB', (width, height), end_color)
mask = Image.new('L', (width, height))
mask_data = []
if is_horizontal:
for x in range(width):
mask_data.extend([int(255 * (x / width))] * height)
else:
for y in range(height):
mask_data.extend([int(255 * (y / height))] * width)
mask.putdata(mask_data)
base.paste(top, (0, 0), mask)
return base
def load_font(font_path=None, font_size=20):
"""
加载字体。优先使用指定的字体路径,如果未指定,则尝试使用系统中常见的中文字体。
如果无法找到中文字体,则使用默认字体(可能不支持中文)。
"""
if font_path and os.path.exists(font_path):
try:
return ImageFont.truetype(font_path, font_size)
except IOError:
print(f"无法加载指定的字体:{font_path}")
# 尝试使用系统中常见的中文字体
common_font_paths = [
"C:/Windows/Fonts/simhei.ttf", # SimHei
"C:/Windows/Fonts/msyh.ttc", # Microsoft YaHei
"C:/Windows/Fonts/simsun.ttc", # SimSun
"/Library/Fonts/STHeiti Medium.ttc", # macOS Heiti
"/System/Library/Fonts/PingFang.ttc", # macOS PingFang
]
for path in common_font_paths:
if os.path.exists(path):
try:
return ImageFont.truetype(path, font_size)
except IOError:
continue
# 回退到默认字体
print("未找到支持中文的字体,使用默认字体,可能无法正确显示中文。")
return ImageFont.load_default()
def wrap_text_chinese(text, draw, font, max_width):
"""
根据最大宽度对中文文本进行换行。
每行尽可能多地添加字符,直到达到最大宽度。
"""
lines = []
current_line = ""
for char in text:
test_line = current_line + char
bbox = draw.textbbox((0, 0), test_line, font=font)
width = bbox[2] - bbox[0]
if width <= max_width:
current_line = test_line
else:
if current_line: # 避免当前行为空
lines.append(current_line)
current_line = char
if current_line:
lines.append(current_line)
return lines
def add_centered_text(image, text, font_path=None, text_color=(255, 255, 255)):
"""在图像中央添加多行文本,自动调整字体大小以适应图像宽度。"""
draw = ImageDraw.Draw(image)
width, height = image.size
max_width = width - 20 # 留出边距
max_height = height - 20
# 初始字体大小
font_size = 40
# 逐步减少字体大小,直到文本适应图像
while font_size >= 10:
font = load_font(font_path, font_size)
lines = wrap_text_chinese(text, draw, font, max_width)
# 计算总文本高度
total_text_height = 0
line_heights = []
for line in lines:
bbox = draw.textbbox((0, 0), line, font=font)
line_height = bbox[3] - bbox[1]
line_heights.append(line_height)
total_text_height += line_height + 5 # 行间距5像素
total_text_height -= 5 # 去掉最后一行的额外间距
# 检查总高度和每行宽度是否符合要求
fits_height = total_text_height <= max_height
fits_width = all((draw.textbbox((0, 0), line, font=font)[2] - draw.textbbox((0, 0), line, font=font)[0]) <= max_width for line in lines)
if fits_height and fits_width:
break
font_size -= 1
if font_size < 10:
print("文本过长,无法适应图像。请尝试使用更短的标题。")
# 重新计算总文本高度
y_start = (height - total_text_height) / 2
for line, line_height in zip(lines, line_heights):
bbox = draw.textbbox((0, 0), line, font=font)
text_width = bbox[2] - bbox[0]
x = (width - text_width) / 2
draw.text((x, y_start), line, font=font, fill=text_color)
y_start += line_height + 5 # 行间距
return image
def generate_feature_image(title, output_path='featured_image.webp', font_path=None):
WIDTH, HEIGHT = 250, 160
# 生成两个随机颜色(避免白色)
start_color = generate_random_color()
end_color = generate_random_color()
# 生成渐变背景
gradient = generate_gradient(WIDTH, HEIGHT, start_color, end_color, is_horizontal=True)
# 添加标题文本
image_with_text = add_centered_text(gradient, title, font_path=font_path, text_color=(255, 255, 255))
# 保存为WebP格式
image_with_text.save(output_path, format='WEBP')
print(f"特色图已保存为 {output_path}")
if __name__ == "__main__":
# 从命令行接收标题输入,如果没有提供,则提示用户输入
if len(sys.argv) > 1:
title = ''.join(sys.argv[1:])
else:
title = input("请输入标题: ")
# 可选:指定字体路径
# 例如,Windows系统常用的中文字体路径:
# font_path = "C:/Windows/Fonts/simhei.ttf"
font_path = "C:/Windows/Fonts/simhei.ttf" # 根据需要修改
if not os.path.exists(font_path):
print(f"指定的字体文件不存在:{font_path}")
print("将尝试使用系统中其他常见的中文字体。")
font_path = None # 使用默认字体或系统中的其他字体
generate_feature_image(title, font_path=font_path)
未经允许不得转载:大神网 » python文章特色图生成器