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

Python Pillow库文本居中失效求助:预期与实际输出不符

Pillow文本居中失效的修复方案

问题描述

我尝试使用Python的Pillow库实现文本居中效果,但未达到预期。预期效果是文本在图片中完全水平垂直居中(类似Photoshop的居中效果),但当前代码生成的文本位置偏右下,未实现真正居中。

原代码如下:

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from PIL import ImageEnhance

# 打开图片并调整尺寸
img = Image.open("input.jpg")
original_width, original_height = img.size
new_height = 720
new_width = int((original_width / original_height) * new_height)
img = img.resize((new_width, new_height), Image.LANCZOS)  # 使用LANCZOS算法抗锯齿

# 将亮度降低至50%
enhancer = ImageEnhance.Brightness(img)
img = enhancer.enhance(0.5)

# 创建绘图对象
I1 = ImageDraw.Draw(img)

# 自定义字体样式和大小
myFont = ImageFont.truetype("Fact-Bold.ttf", 105)

# 计算文本居中位置(原错误逻辑)
text_x = (img.width) // 2
text_y = (img.height) // 2

# 添加文本到图片
I1.text((text_x, text_y), "Movies", font=myFont, fill=(255, 255, 255))

# 显示编辑后的图片
img.show()

问题原因

ImageDraw.text()方法默认以传入的坐标作为文本的左上角起点,而非文本的中心点。直接用图片宽高的一半作为坐标,会让文本左上角落在图片中心,导致整体位置偏右下。

修复方案

先计算文本的实际尺寸,再基于图片尺寸算出真正的居中坐标:

修改后的完整代码

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from PIL import ImageEnhance

# 打开图片并调整尺寸
img = Image.open("input.jpg")
original_width, original_height = img.size
new_height = 720
new_width = int((original_width / original_height) * new_height)
img = img.resize((new_width, new_height), Image.LANCZOS)

# 将亮度降低至50%
enhancer = ImageEnhance.Brightness(img)
img = enhancer.enhance(0.5)

# 创建绘图对象
I1 = ImageDraw.Draw(img)
myFont = ImageFont.truetype("Fact-Bold.ttf", 105)

text = "Movies"
# 关键修改:获取文本边界框并计算居中坐标
# textbbox返回(left, top, right, bottom),代表文本的完整边界
bbox = I1.textbbox((0, 0), text, font=myFont)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]

# 计算真正的居中坐标
text_x = (img.width - text_width) // 2
text_y = (img.height - text_height) // 2

# 添加文本到图片
I1.text((text_x, text_y), text, font=myFont, fill=(255, 255, 255))

# 显示编辑后的图片
img.show()

补充说明

  • 对于Pillow 9.1.0及以上版本,推荐使用textbbox()方法获取文本边界框,它能更准确处理不同字体的字形偏移,返回值包含文本的完整边界信息。
  • 如果使用旧版Pillow,可以用myFont.getsize(text)获取文本宽高(返回(width, height)),替换上述bbox相关计算即可。

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

相关产品推荐
方舟 Agent Plan

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

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