在Python可视化、图像处理、报表生成等场景中,经常需要在图像或画布上绘制文字(如标注信息、标题、说明文字等)。不同的绘图库(Pillow、OpenCV、Matplotlib)在文字绘制功能上各有侧重,适用于不同场景。本文档将系统介绍这三个常用库的文字绘制方法,详细讲解核心参数、代码示例及常见问题解决办法,帮助开发者快速掌握Python文字绘制技巧。
一、基础准备:常用库介绍与安装
Python中支持文字绘制的核心库有三个,各自定位不同:
•Pillow:轻量易用的图像处理库,适合在图像上快速叠加文字,支持字体、颜色、位置等基础设置;
•OpenCV:侧重计算机视觉,可在处理后的图像上绘制文字(如目标检测标注),需注意色彩模式和字体路径;
•Matplotlib:专业的绘图库,适合在图表中添加标题、坐标轴标签、注释等文字,支持复杂的文字排版。
以下是各库的安装命令:
1.1 Pillow库安装
python# 使用pip安装Pillowpip install pillow |
1.2 OpenCV库安装
python# 使用pip安装OpenCV(安装包名为opencv-python)pip install opencv-python |
1.3 Matplotlib库安装
python# 使用pip安装Matplotlibpip install matplotlib |
二、Pillow库:在图像上绘制文字(简单高效)
Pillow通过PIL.ImageDraw.ImageDraw类实现文字绘制,需先创建绘图对象,再调用text()方法绘制文字。核心优势是API简洁,支持多种字体和文字样式,适合快速在图像上添加标注。
2.1 核心步骤与代码示例
基本流程:打开/创建图像 → 创建绘图对象 → 配置字体(可选,解决中文显示问题) → 绘制文字 → 保存/显示图像。
pythonfrom PIL import Image, ImageDraw, ImageFontimport os# 1. 准备工作:获取字体路径(解决中文显示问题,需本地有对应字体文件)# Windows默认字体路径:C:/Windows/Fonts/;macOS:/System/Library/Fonts/;Linux:/usr/share/fonts/font_path = os.path.join("C:/Windows/Fonts", "simhei.ttf") # 黑体字体(支持中文)# 若字体文件不存在,可省略font参数(默认使用默认字体,可能不支持中文)try:# 方式1:在现有图像上绘制文字img_path = os.path.join(os.getcwd(), "test_image.jpg")with Image.open(img_path) as img:# 创建绘图对象(绑定到图像)draw = ImageDraw.Draw(img)# 配置字体(指定字体和字号,字号单位为像素)font = ImageFont.truetype(font_path, 40) # 40号字体# 绘制文字:text(位置, 文字内容, 颜色, 字体, 对齐方式等)# 位置:(x, y),表示文字左上角的坐标(x向右为正,y向下为正)# 颜色:支持RGB元组、十六进制字符串、颜色名称draw.text(xy=(50, 50), # 文字左上角坐标text="Pillow绘制文字示例\n中文测试(黑体40号)",fill=(255, 0, 0), # 红色文字(RGB)font=font,align="left" # 多行文字对齐方式(left/center/right))# 可选:绘制带背景色的文字(先画矩形,再画文字)text_bg = "带背景色的文字"# 计算文字尺寸(获取文字的宽高,用于绘制背景矩形)text_width, text_height = draw.textbbox((0, 0), text_bg, font=font)[2:]# 绘制背景矩形(位置覆盖文字区域,颜色为黄色)draw.rectangle([100, 200, 100 + text_width, 200 + text_height], # [x1, y1, x2, y2] 矩形对角线坐标fill=(255, 255, 0))# 绘制文字(叠加在矩形上)draw.text((100, 200), text_bg, fill=(0, 0, 255), font=font)# 保存绘制后的图像img.save("pillow_text_image.jpg")print("文字绘制完成,保存为:pillow_text_image.jpg")# 方式2:创建空白图像并绘制文字with Image.new("RGB", (800, 400), color=(255, 255, 255)) as blank_img: # 800x400的白色空白图draw = ImageDraw.Draw(blank_img)font = ImageFont.truetype(font_path, 50)draw.text((100, 150), "空白图像绘制文字", fill=(0, 128, 0), font=font)blank_img.save("pillow_blank_text.jpg")print("空白图像文字绘制完成,保存为:pillow_blank_text.jpg")except FileNotFoundError as e:print(f"错误:文件不存在 - {str(e)}")except Exception as e:print(f"错误:绘制失败 - {str(e)}") |
2.2 核心参数说明
•xy=(x, y):文字左上角的坐标,是绘制文字的核心参数,需根据图像尺寸调整位置,避免文字超出图像范围;
•text:要绘制的文字内容,支持换行符\n实现多行文字;
•fill:文字颜色,可传入:
○RGB元组:如(255, 0, 0)(红色);
○十六进制字符串:如"#FF0000";
○颜色名称:如"red"(仅支持英文颜色名)。
•font:字体对象,通过ImageFont.truetype(字体路径, 字号)创建,必须指定本地存在的字体文件才能支持中文;
•align:多行文字的对齐方式,可选"left"(默认)、"center"、"right";
•stroke_width(可选):文字描边宽度,如stroke_width=2;
•stroke_fill(可选):文字描边颜色,如stroke_fill=(0, 0, 0)(黑色描边)。
三、OpenCV库:在图像上绘制文字(视觉任务适配)
OpenCV通过cv2.putText()方法绘制文字,核心优势是可与图像识别、目标检测等视觉任务无缝衔接,适合在处理后的图像上添加标注(如目标框上方的类别文字)。需注意:OpenCV默认不支持中文,需通过加载字体文件解决;且默认使用BGR色彩模式,颜色参数需与模式匹配。
3.1 核心步骤与代码示例
基本流程:读取/创建图像 → 配置字体(解决中文显示) → 绘制文字 → 保存/显示图像。
pythonimport cv2import numpy as npfrom PIL import ImageFont, ImageDraw, Imageimport os# 1. 准备工作:获取字体路径(同Pillow)font_path = os.path.join("C:/Windows/Fonts", "simhei.ttf")def cv2_draw_text(img, text, xy, font_path, font_size=30, color=(0, 0, 255)):"""OpenCV绘制中文文字的封装函数(解决OpenCV默认不支持中文的问题):param img: OpenCV图像(NumPy数组):param text: 要绘制的文字:param xy: 文字左上角坐标 (x, y):param font_path: 字体文件路径:param font_size: 字号:param color: 文字颜色(BGR模式,默认红色):return: 绘制文字后的图像"""# 转换图像模式:BGR(OpenCV默认)→ RGB(Pillow支持)img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 创建Pillow绘图对象draw = ImageDraw.Draw(Image.fromarray(img_rgb))# 配置字体font = ImageFont.truetype(font_path, font_size)# 绘制文字draw.text(xy, text, fill=color[::-1], font=font) # color[::-1]:BGR→RGB# 转换回BGR模式return cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)try:# 方式1:在现有图像上绘制文字(含中文)img_path = os.path.join(os.getcwd(), "test_image.jpg")img = cv2.imread(img_path)if img is None:raise FileNotFoundError("未找到图像文件")# 绘制英文文字(OpenCV原生支持英文,无需转换)# cv2.putText(图像, 文字, 坐标, 字体类型, 字号缩放系数, 颜色, 线条宽度)cv2.putText(img,"OpenCV Text Demo",(50, 50), # 文字左下角坐标(注意:与Pillow的左上角不同)cv2.FONT_HERSHEY_SIMPLEX, # 内置英文字体1.2, # 字号缩放系数(大于1放大,小于1缩小)(0, 255, 0), # 绿色(BGR模式)2 # 文字线条宽度)# 绘制中文文字(调用封装函数)img = cv2_draw_text(img=img,text="中文标注测试(OpenCV)",xy=(50, 100),font_path=font_path,font_size=35,color=(0, 0, 255) # 红色(BGR模式))# 方式2:在空白图像上绘制文字blank_img = np.ones((400, 800, 3), dtype=np.uint8) * 255 # 400x800的白色空白图(BGR)blank_img = cv2_draw_text(blank_img, "OpenCV空白图像中文", (100, 200), font_path, 40, (255, 0, 0))# 保存并显示图像cv2.imwrite("opencv_text_image.jpg", img)cv2.imwrite("opencv_blank_text.jpg", blank_img)# 显示图像(按任意键关闭)cv2.imshow("Text Demo", img)cv2.imshow("Blank Text Demo", blank_img)cv2.waitKey(0)cv2.destroyAllWindows()print("OpenCV文字绘制完成,已保存图像")except FileNotFoundError as e:print(f"错误:{str(e)}")except Exception as e:print(f"错误:绘制失败 - {str(e)}") |
3.2 核心参数与注意事项
•坐标差异:OpenCV的cv2.putText()的坐标是文字左下角的坐标,而Pillow是左上角,需注意区分,避免位置偏差;
•中文支持:OpenCV内置字体仅支持英文,绘制中文需借助Pillow转换图像模式(如上述封装函数),或加载中文字体文件(较复杂);
•色彩模式:OpenCV默认使用BGR模式,颜色参数需传入BGR元组(如红色为(0, 0, 255)),与Pillow的RGB模式相反;
•内置字体:通过cv2.FONT_*指定,如cv2.FONT_HERSHEY_SIMPLEX(简洁字体)、cv2.FONT_HERSHEY_COMPLEX(复杂字体);
•字号缩放系数:fontScale参数控制字号大小,无固定单位,需根据图像尺寸调整(如1.0对应基础字号,2.0放大一倍)。
四、Matplotlib库:图表/画布文字绘制(专业排版)
Matplotlib是专业的绘图库,支持在图表中添加标题、坐标轴标签、图例、注释等多种文字元素,文字排版功能强大,支持中文,适合数据可视化场景中的文字标注。
4.1 核心步骤与代码示例
基本流程:创建画布/子图 → 绘制图表(可选) → 添加各类文字元素 → 显示/保存图像。
pythonimport matplotlib.pyplot as pltimport numpy as np# 1. 解决中文显示问题(设置中文字体)plt.rcParams['font.sans-serif'] = ['SimHei'] # 黑体(Windows),macOS可设为'Arial Unicode MS'plt.rcParams['axes.unicode_minus'] = False # 解决负号显示异常问题try:# 创建画布和子图(1行1列的子图)fig, ax = plt.subplots(figsize=(10, 6)) # figsize:画布尺寸(宽,高),单位为英寸# 绘制示例图表(折线图)x = np.linspace(0, 10, 100)y = np.sin(x)ax.plot(x, y, label='sin(x) 曲线')# 1. 添加标题(画布标题和子图标题)fig.suptitle('Matplotlib文字绘制示例', fontsize=16, fontweight='bold', y=0.95) # 画布总标题ax.set_title('正弦函数曲线及文字标注', fontsize=14, pad=20) # 子图标题(pad:与图表的间距)# 2. 添加坐标轴标签ax.set_xlabel('X轴(自变量)', fontsize=12, labelpad=10)ax.set_ylabel('Y轴(sin(x)值)', fontsize=12, labelpad=10)# 3. 添加图例(对应plot的label参数)ax.legend(loc='upper right', fontsize=10) # loc:图例位置# 4. 添加注释文字(标注特定点)# annotate(注释内容, 目标点坐标, 注释文字坐标, 箭头参数)ax.annotate('最大值点\n(y=1)', # 注释文字(支持换行)xy=(np.pi/2, 1), # 目标点(sin(x)的最大值点)xytext=(np.pi/2 + 1, 1.2), # 注释文字的位置fontsize=10,color='red',arrowprops=dict(arrowstyle='->', color='red', lw=1.5) # 箭头样式)# 5. 添加任意位置的文字ax.text(6, -0.8, # 文字位置(基于坐标轴坐标,非像素)'文字说明:\nsin(x)在[0,10]区间的变化曲线',fontsize=10,bbox=dict(boxstyle='round,pad=0.5', facecolor='yellow', alpha=0.5) # 文字背景框)# 6. 调整布局(避免文字被截断)plt.tight_layout()# 保存和显示plt.savefig('matplotlib_text_demo.png', dpi=300, bbox_inches='tight')plt.show()print("Matplotlib文字绘制完成,已保存图像")except Exception as e:print(f"错误:绘制失败 - {str(e)}") |
4.2 核心文字元素说明
•画布标题(fig.suptitle()):整个画布的总标题,位于画布顶部;
•子图标题(ax.set_title()):单个子图的标题,位于子图上方;
•坐标轴标签(ax.set_xlabel()/ax.set_ylabel()):X轴和Y轴的说明文字,位于坐标轴下方/左侧;
•图例(ax.legend()):解释图表中各类元素的含义,需配合plot()的label参数使用;
•注释(ax.annotate()):用于标注图表中的特定点,支持添加箭头,适合强调关键数据;
•自由文字(ax.text()):可在子图任意位置添加文字,支持背景框样式自定义。
五、三种库的对比与适用场景
对比维度 | Pillow库 | OpenCV库 | Matplotlib库 |
核心优势 | API简洁,中文支持简单,适合快速在图像上叠加文字 | 与视觉任务无缝衔接,适合目标检测、图像识别中的标注 | 文字排版专业,支持多种文字元素,适合数据可视化图表 |
中文支持 | 直接加载字体文件即可,简单易用 | 原生不支持,需借助Pillow转换,稍复杂 | 通过rcParams设置中文字体,简单 |
坐标体系 | 像素坐标(左上角为原点) | 像素坐标(左下角为原点) | 坐标轴坐标(与数据范围匹配) |
适用场景 | 图像标注、简单文字叠加、批量图像处理中的文字添加 | 计算机视觉项目(目标检测、人脸识别)中的实时标注 | 数据可视化图表(折线图、柱状图)的标题、注释、图例 |
缺点 | 不支持复杂图表绘制,仅适用于图像 | 文字排版功能弱,中文处理繁琐 | 图像处理功能弱,不适合纯图像的文字叠加 |
六、常见问题与解决办法
•中文显示乱码/无法显示:
○Pillow/OpenCV:确保加载了本地存在的中文字体文件(如simhei.ttf、simfang.ttf),并正确指定字体路径;
○Matplotlib:通过plt.rcParams['font.sans-serif']设置正确的中文字体名称,同时设置plt.rcParams['axes.unicode_minus'] = False解决负号显示问题。
•文字超出图像范围:
○Pillow/OpenCV:通过ImageDraw.textbbox()计算文字宽高,再根据图像尺寸调整文字坐标;
○Matplotlib:使用plt.tight_layout()自动调整布局,或手动调整画布尺寸(figsize)。
•文字模糊:
○Pillow/OpenCV:增大字号,或在保存图像时提高分辨率(如Pillow保存时指定dpi=300);
○Matplotlib:保存图像时指定较高的dpi参数(如dpi=300)。
•OpenCV文字颜色错误:忘记OpenCV的BGR色彩模式,将RGB颜色直接传入,需将颜色元组反转(如(255,0,0)→(0,0,255))。
总结:Python绘制文字需根据具体场景选择合适的库——简单图像文字叠加选Pillow,视觉任务标注选OpenCV,数据可视化图表文字排版选Matplotlib。核心是掌握各库的坐标体系、中文支持方法和核心参数,结合实际需求调整文字位置、样式和大小。通过本文档的代码示例和说明,可快速上手各类文字绘制场景,解决常见问题。