简介:本文深入探讨如何使用Python在照片上添加中文文字,涵盖字体处理、坐标定位、样式调整及常见问题解决方案,提供从基础到进阶的完整实现路径。
在图像处理领域,为照片添加文字是常见的需求,而中文文字的特殊编码和字体结构使其处理更具挑战性。本文将系统介绍如何使用Python实现照片中文文字添加,涵盖字体选择、坐标定位、样式调整等核心环节,并提供完整代码示例和优化方案。
实现该功能主要依赖Pillow(PIL)和OpenCV两个库:
pip install pillow opencv-python
Pillow提供基础的图像处理功能,而OpenCV可用于更复杂的图像操作。建议同时安装numpy以支持数组操作。
Windows系统通常自带中文字体(如simhei.ttf),Linux/macOS需手动安装:
# Ubuntu示例sudo apt-get install fonts-wqy-zenhei
或从网络下载字体文件(.ttf格式),确保程序能访问到字体路径。
from PIL import Image, ImageDraw, ImageFontdef add_chinese_text(image_path, text, position, font_path, font_size=20, color=(255,255,255)):"""在图片上添加中文文字:param image_path: 图片路径:param text: 要添加的文字:param position: 文字位置(x,y):param font_path: 字体文件路径:param font_size: 字体大小:param color: 文字颜色(RGB):return: 处理后的图片"""image = Image.open(image_path)draw = ImageDraw.Draw(image)# 加载中文字体try:font = ImageFont.truetype(font_path, font_size)except IOError:print("字体文件加载失败,请检查路径")return imagedraw.text(position, text, font=font, fill=color)return image# 使用示例image = add_chinese_text("input.jpg","你好,世界!",(50, 50),"simhei.ttf",40,(255, 0, 0))image.save("output.jpg")
def add_wrapped_text(image_path, text, position, font_path, font_size, max_width, color=(255,255,255)):image = Image.open(image_path)draw = ImageDraw.Draw(image)font = ImageFont.truetype(font_path, font_size)lines = []current_line = ""for word in text:test_line = current_line + wordtest_width = draw.textlength(test_line, font=font) # 或使用textsize()[0]if test_width < max_width:current_line = test_lineelse:lines.append(current_line)current_line = wordlines.append(current_line)y_position = position[1]for line in lines:draw.text((position[0], y_position), line, font=font, fill=color)y_position += font_size + 5 # 行间距return image
def add_text_with_outline(image_path, text, position, font_path, font_size, color, outline_color, outline_width=2):image = Image.open(image_path).convert("RGBA")txt = Image.new("RGBA", image.size, (255,255,255,0))draw = ImageDraw.Draw(txt)font = ImageFont.truetype(font_path, font_size)# 绘制描边for x in range(-outline_width, outline_width+1):for y in range(-outline_width, outline_width+1):if x != 0 or y != 0: # 跳过中心点draw.text((position[0]+x, position[1]+y), text, font=font, fill=outline_color)# 绘制正文draw.text(position, text, font=font, fill=color)# 合并图层result = Image.alpha_composite(image, txt)return result.convert("RGB")
原因:字体文件不包含所需中文字符
解决方案:
try:font = ImageFont.truetype("font.ttf", 20)# 测试绘制常见中文字符test_char = "测试"# 若不报错则字体可用except Exception as e:print(f"字体错误: {e}")
优化方案:
def get_text_size(text, font_path, font_size):"""获取文字尺寸"""font = ImageFont.truetype(font_path, font_size)# PIL 5.0+ 使用textbboxtry:bbox = font.getbbox(text)return (bbox[2]-bbox[0], bbox[3]-bbox[1])except AttributeError:# 旧版本兼容draw = ImageDraw.Draw(Image.new("RGB", (1,1)))return draw.textsize(text, font=font)
def get_cached_font(font_path, size):
key = (font_path, size)
if key not in font_cache:
font_cache[key] = ImageFont.truetype(font_path, size)
return font_cache[key]
2. **批量处理**:对多张图片添加相同文字时,可复用Draw对象3. **异步处理**:使用多进程处理大量图片```pythonfrom multiprocessing import Pooldef process_image(args):return add_chinese_text(*args)def batch_process(image_paths, text, positions, font_path):args = [(path, text, pos, font_path) for path, pos in zip(image_paths, positions)]with Pool(4) as p: # 4个进程results = p.map(process_image, args)return results
import osfrom PIL import Image, ImageDraw, ImageFontclass ImageTextAdder:def __init__(self, default_font="simhei.ttf"):self.default_font = default_fontself.font_cache = {}def _get_font(self, size):key = (self.default_font, size)if key not in self.font_cache:self.font_cache[key] = ImageFont.truetype(self.default_font, size)return self.font_cache[key]def add_text(self, image_path, output_path, text, position,font_size=20, color=(255,255,255),font_path=None, outline=None):""":param outline: (outline_color, outline_width)"""image = Image.open(image_path)draw = ImageDraw.Draw(image)font_path = font_path or self.default_fontfont = self._get_font(font_size)if outline:outline_color, outline_width = outlinefor x in range(-outline_width, outline_width+1):for y in range(-outline_width, outline_width+1):if x != 0 or y != 0:draw.text((position[0]+x, position[1]+y), text,font=font, fill=outline_color)draw.text(position, text, font=font, fill=color)image.save(output_path)return output_path# 使用示例if __name__ == "__main__":adder = ImageTextAdder(default_font="msyh.ttc") # 微软雅黑adder.add_text("input.jpg","output.jpg","Python中文处理示例",(50, 50),font_size=36,color=(0, 120, 215),outline=((255, 255, 255), 2))
字体选择:
颜色搭配:
位置规范:
通过本文介绍的完整方案,开发者可以轻松实现Python照片中文文字添加功能,并根据实际需求进行扩展优化。实际开发中,建议将文字添加功能封装为独立模块,便于在图像处理流水线中复用。