You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动调整证书字体大小并居中适配指定像素空间?

解决方案:自动适配空间的证书姓名写入

核心思路

  1. 锁定姓名区域边界:根据你提供的起始/结束坐标,计算出姓名可占用的水平宽度(垂直位置若固定则直接沿用给定y值)。
  2. 动态匹配字体大小:从足够大的字号开始逐步缩小,直到文本宽度刚好适配指定区域,保证字体尽可能大且不溢出。
  3. 精准计算居中位置:基于区域中心和文本宽度,算出文本的起始x坐标,实现水平居中对齐。

完整实现代码

from PIL import Image, ImageDraw, ImageFont
import pandas as pd

# 配置参数(替换为你的实际值)
CERTIFICATE_PATH = r"C:\Documents\Certificate\Effort.png"
# 姓名区域坐标:x起始,x结束,y垂直位置
NAME_AREA = (553, 1500, 3023)  # 需替换x_end为你的实际结束像素
FONT_PATH = r"C:\Windows\Fonts\msyh.ttc"  # 替换为你想用的字体路径
MAX_FONT_SIZE = 100  # 初始尝试的最大字号
MIN_FONT_SIZE = 10   # 字号下限,避免过小

# 读取Excel学员名单
df = pd.read_excel("学员名单.xlsx")
student_names = df["姓名"].tolist()

for name in student_names:
    # 打开证书图片
    im = Image.open(CERTIFICATE_PATH)
    draw = ImageDraw.Draw(im)
    x_start, x_end, y_pos = NAME_AREA
    available_width = x_end - x_start

    # 从大到小尝试字体,找到适配的最大字号
    font_size = MAX_FONT_SIZE
    while font_size > MIN_FONT_SIZE:
        font = ImageFont.truetype(FONT_PATH, font_size)
        text_width, text_height = draw.textsize(name, font=font)
        if text_width <= available_width:
            break
        font_size -= 2  # 步长可按需调整

    # 计算水平居中的x坐标
    x_center = (x_start + x_end) / 2
    text_x = x_center - (text_width / 2)
    # 若需垂直居中,取消下方注释,否则直接用原始y_pos
    # text_y = y_pos - (text_height / 2)

    # 写入姓名(fill为字体颜色,按需调整)
    draw.text((text_x, y_pos), name, font=font, fill=(0, 0, 0))

    # 保存生成的证书
    im.save(f"结业证书_{name}.png")

关键细节说明

  • 路径处理:用原始字符串r"..."避免Windows路径的转义错误。
  • 字体适配逻辑:从大字号迭代测试,确保在不超出区域的前提下使用最大字号,兼顾美观和适配性。
  • 居中计算:通过区域中心减去文本宽度的一半,实现精准水平居中;若姓名区域有垂直高度,可复用逻辑调整y坐标实现垂直居中。
  • 批量处理:结合Pandas读取的学员名单,自动批量生成每个学员的专属证书。

注意事项

  • 务必替换NAME_AREA中的x_end为你实际的结束像素坐标。
  • 字体路径需确保有效,Windows系统字体默认在C:\Windows\Fonts目录,也可使用自定义字体文件。
  • 可调整MAX_FONT_SIZE和字号缩小步长(font_size -= 2)来适配不同证书的布局需求。

内容的提问来源于stack exchange,提问作者Riff55

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:55:01