Pillow 绘图中文乱码
Pillow 绘图中文乱码 终极解决方案
问题原因:Pillow 默认字体不支持中文,导致
□或乱码
1. 快速解决方案(推荐)
方法一:使用系统中文字体(最简单)
from PIL import Image, ImageDraw, ImageFont
# Windows 系统字体路径
font_path = "C:/Windows/Fonts/simhei.ttf" # 黑体
# font_path = "C:/Windows/Fonts/msyh.ttc" # 微软雅黑
# macOS 系统字体路径
# font_path = "/System/Library/Fonts/PingFang.ttc"
# Linux 系统字体路径
# font_path = "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"
img = Image.new('RGB', (400, 200), color='white')
draw = ImageDraw.Draw(img)
# 加载中文字体
font = ImageFont.truetype(font_path, 36)
# 绘制中文
draw.text((20, 80), "你好,世界!Pillow中文无乱码", font=font, fill='red')
img.save("chinese_ok.jpg")
img.show()
2. 跨平台自动字体检测(推荐使用)
from PIL import Image, ImageDraw, ImageFont
import os
import platform
def get_chinese_font(size=32):
"""自动获取系统中文字体"""
system = platform.system()
font_paths = {
'Windows': [
"C:/Windows/Fonts/simhei.ttf", # 黑体
"C:/Windows/Fonts/msyh.ttc", # 微软雅黑
"C:/Windows/Fonts/simkai.ttf", # 楷体
],
'Darwin': [ # macOS
"/System/Library/Fonts/PingFang.ttc",
"/System/Library/Fonts/STHeiti Light.ttc",
"/Library/Fonts/Arial Unicode.ttf",
],
'Linux': [
"/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
"/usr/share/fonts/opentype/wqy/WenQuanYiZenHei.otf",
"/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc",
]
}
for font_path in font_paths.get(system, []):
if os.path.exists(font_path):
return ImageFont.truetype(font_path, size)
# 默认字体(无中文)
return ImageFont.load_default()
# 使用
img = Image.new('RGB', (500, 300), 'white')
draw = ImageDraw.Draw(img)
font = get_chinese_font(40)
texts = ["Pillow中文测试", "黑体效果很好", "你好世界!😊"]
for i, text in enumerate(texts):
draw.text((20, 50 + i*60), text, font=font, fill='blue')
img.save("auto_font.jpg")
3. 一键下载免费中文字体
import requests
import os
from PIL import Image, ImageDraw, ImageFont
def download_chinese_font():
"""下载开源中文字体"""
font_url = "https://github.com/googlefonts/noto-fonts/raw/main/hinted/ttf/NotoSansSC/NotoSansSC-Regular.ttf"
font_path = "NotoSansSC-Regular.ttf"
if not os.path.exists(font_path):
print("正在下载中文字体...")
response = requests.get(font_url)
with open(font_path, 'wb') as f:
f.write(response.content)
print("字体下载完成!")
return font_path
# 使用
font_path = download_chinese_font()
font = ImageFont.truetype(font_path, 36)
img = Image.new('RGB', (600, 400), 'white')
draw = ImageDraw.Draw(img)
draw.text((50, 150), "谷歌思源黑体\n完美支持中文!", font=font, fill=(255, 0, 0))
img.save("google_font.jpg")
4. 完整水印工具(支持中文)
from PIL import Image, ImageDraw, ImageFont
import os
class ChineseWatermark:
def __init__(self):
self.font = self._get_font(40)
def _get_font(self, size):
"""智能字体选择"""
font_paths = [
"NotoSansSC-Regular.ttf", # 自下载
"C:/Windows/Fonts/simhei.ttf", # Windows
"/System/Library/Fonts/PingFang.ttc", # macOS
]
for path in font_paths:
if os.path.exists(path):
return ImageFont.truetype(path, size)
return ImageFont.load_default()
def add_text(self, img_path, output_path, text="© 2025", position="bottom-right"):
img = Image.open(img_path).convert("RGBA")
draw = ImageDraw.Draw(img)
# 计算文字位置
bbox = draw.textbbox((0, 0), text, font=self.font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
w, h = img.size
if position == "bottom-right":
x, y = w - text_width - 20, h - text_height - 20
elif position == "center":
x, y = (w - text_width) // 2, (h - text_height) // 2
# 半透明文字
draw.text((x, y), text, font=self.font, fill=(255, 255, 255, 180))
# 保存为透明PNG
img.convert("RGB").save(output_path)
print(f"水印添加完成: {output_path}")
# 使用
wm = ChineseWatermark()
wm.add_text("photo.jpg", "watermarked.jpg", "摄影/张三 2025", "bottom-right")
5. 常见字体文件路径对照表
| 系统 | 字体名称 | 文件路径 |
|---|---|---|
| Windows | 黑体 | C:/Windows/Fonts/simhei.ttf |
| 微软雅黑 | C:/Windows/Fonts/msyh.ttc | |
| 楷体 | C:/Windows/Fonts/simkai.ttf | |
| macOS | 苹方 | /System/Library/Fonts/PingFang.ttc |
| 黑体 | /System/Library/Fonts/STHeiti Light.ttc | |
| Linux | 文泉驿 | /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc |
| 通用 | 思源黑体 | 下载 NotoSansSC-Regular.ttf |
6. 调试工具:测试所有系统字体
from PIL import ImageFont
import os
def test_all_fonts():
"""测试系统所有可用的字体"""
test_text = "中文字体测试"
# Windows 字体目录
font_dirs = [
"C:/Windows/Fonts",
"/System/Library/Fonts",
"/usr/share/fonts"
]
for font_dir in font_dirs:
if os.path.exists(font_dir):
for font_file in os.listdir(font_dir):
if font_file.endswith(('.ttf', '.ttc', '.otf')):
try:
font_path = os.path.join(font_dir, font_file)
font = ImageFont.truetype(font_path, 24)
# 这里可以添加实际测试代码
print(f"✓ {font_file}")
except:
pass
test_all_fonts()
7. 一行解决(终极懒人法)
from PIL import Image, ImageDraw, ImageFont
font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 36) # Windows
# font = ImageFont.truetype("/System/Library/Fonts/PingFang.ttc", 36) # macOS
🚀 立即可用完整代码
from PIL import Image, ImageDraw, ImageFont
import platform
# 自动选择字体
system = platform.system()
if system == "Windows":
font = ImageFont.truetype("simhei.ttf", 48)
elif system == "Darwin":
font = ImageFont.truetype("/System/Library/Fonts/PingFang.ttc", 48)
else:
font = ImageFont.truetype("NotoSansSC-Regular.ttf", 48)
# 创建图片
img = Image.new('RGB', (800, 600), 'lightblue')
draw = ImageDraw.Draw(img)
# 中文标题
draw.text((100, 200), "🎉 Pillow中文完美解决!", font=font, fill='darkred')
draw.text((100, 300), "黑体 微软雅黑 苹方", font=font, fill='navy')
img.save("中文成功.png")
img.show()
总结:优先使用系统字体路径,路径不对就下载思源黑体,乱码问题 100% 解决!
需要我帮你写 批量加中文水印工具 或 字体管理器 吗?