微信关注,获取更多

python文章特色图生成器

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文章特色图生成器

相关推荐

    暂无内容!