如何在PIL(Pillow)中利用转义序列实现文本部分着色?
用PIL实现文本部分变色的正确方法
尝试用PIL在图片上添加带ANSI转义序列
\033[32m的文本,期望让"person"变为绿色,但转义序列被当作普通字符显示,无法实现预期效果。原代码如下:
from PIL import Image, ImageDraw, ImageFont image = Image.new('RGB', (950, 250), color=(255, 255, 255)) TEXT = 'You are a wonderful \033[32mperson.' font_size = 50 font_type = "SourceCodePro-Bold.ttf" draw = ImageDraw.Draw(im=image) font = ImageFont.truetype(font_type, font_size) draw.multiline_text((int(950 / 2), int(250 / 2)), text=TEXT, font=font,fill=(0, 0, 0), anchor='mm') image.show()
PIL的draw.text和multiline_text方法不支持ANSI转义序列,要实现部分文本变色,需要手动拆分文本段落,分别指定颜色绘制,并通过计算文本宽度来保证段落衔接对齐。
基础实现代码
from PIL import Image, ImageDraw, ImageFont image = Image.new('RGB', (950, 250), color=(255, 255, 255)) font_size = 50 font_type = "SourceCodePro-Bold.ttf" draw = ImageDraw.Draw(im=image) font = ImageFont.truetype(font_type, font_size) # 拆分文本及对应颜色 text_parts = [ ('You are a wonderful ', (0, 0, 0)), # 黑色 ('person.', (0, 128, 0)) # 绿色 ] # 计算所有文本总宽度,用于居中对齐 total_width = sum(draw.textlength(text, font=font) for text, _ in text_parts) center_x = (950 - total_width) / 2 center_y = 250 / 2 current_x = center_x for text, color in text_parts: # 用lm锚点(左垂直居中)保证段落衔接 draw.text((current_x, center_y), text, font=font, fill=color, anchor='lm') current_x += draw.textlength(text, font=font) image.show()
封装成可复用函数
如果需要处理多段颜色文本,可以封装成函数简化调用:
def draw_multi_color_text(draw, center_pos, text_segments, font): total_width = sum(draw.textlength(text, font=font) for text, _ in text_segments) # 计算起始X坐标(基于整体居中) start_x = center_pos[0] - total_width / 2 start_y = center_pos[1] current_x = start_x for text, color in text_segments: draw.text((current_x, start_y), text, font=font, fill=color, anchor='mm') current_x += draw.textlength(text, font=font) # 调用示例 text_segments = [ ('You are a ', (0,0,0)), ('wonderful ', (255,0,0)), ('person.', (0,128,0)) ] draw_multi_color_text(draw, (950/2, 250/2), text_segments, font)
关键说明
draw.textlength():用于计算文本在指定字体下的宽度,确保段落衔接准确anchor参数:使用lm(左垂直居中)或mm(居中)锚点,保证文本对齐方式一致- RGB颜色值:直接传入颜色元组,比如绿色用
(0,128,0),可根据需求调整
内容的提问来源于stack exchange,提问作者P. Roy
相关产品推荐
相关产品推荐

