Pillow ImageDraw 模块 全解析
图像上的 “画笔” —— 绘制文字、线条、矩形、圆形、多边形、点阵…
1. 模块导入
from PIL import Image, ImageDraw, ImageFont
ImageDraw.Draw()是绘图入口
2. 创建绘图对象
img = Image.open("bg.jpg").convert("RGBA")
draw = ImageDraw.Draw(img) # 绑定到图像
所有绘图操作都通过
draw对象完成
3. 基础绘图方法 速查表
| 方法 | 功能 | 关键参数 |
|---|---|---|
draw.text() | 写文字 | xy, text, font=, fill= |
draw.line() | 画线 | xy, fill=, width= |
draw.rectangle() | 画矩形 | xy, fill=, outline=, width= |
draw.ellipse() | 画圆/椭圆 | xy, fill=, outline= |
draw.polygon() | 画多边形 | xy, fill=, outline= |
draw.point() | 画点 | xy, fill= |
draw.arc() | 画弧 | xy, start, end |
draw.chord() | 画弦 | xy, start, end |
draw.pieslice() | 画扇形 | xy, start, end |
4. 详细用法示例
1. text() —— 绘制文字(支持中文)
# 加载字体(必须!)
font = ImageFont.truetype("simhei.ttf", 48) # Windows 黑体
# font = ImageFont.truetype("/System/Library/Fonts/PingFang.ttc", 48) # macOS
draw.text((100, 50), "你好 Pillow!", font=font, fill="red")
文字对齐(Pillow 9.0+)
draw.text((100, 50), "居中文字", font=font, fill="blue", anchor="mm")
# anchor: "lt" 左上, "mm" 中心, "rb" 右下
2. line() —— 画线
draw.line([(0, 0), (200, 300)], fill="green", width=5)
# 多段线
draw.line([(50,50), (150,50), (100,150)], fill="purple", width=3)
3. rectangle() —— 矩形
# 坐标格式:[左上, 右下] 或 (x1,y1,x2,y2)
draw.rectangle([100, 100, 300, 200], fill="skyblue", outline="navy", width=4)
# 圆角矩形(Pillow 7.0+)
draw.rounded_rectangle([150, 150, 350, 250], radius=30, fill="pink", outline="red", width=3)
4. ellipse() —— 圆形 / 椭圆
draw.ellipse([200, 200, 400, 300], fill="yellow", outline="orange", width=5)
# 画圆(宽高相等)
draw.ellipse([250, 250, 350, 350], fill="lightgreen")
5. polygon() —— 多边形
# 三角形
draw.polygon([(300, 100), (400, 200), (200, 200)], fill="gold", outline="black")
# 五角星(复杂)
star = [(350, 150), (370, 200), (420, 200), (380, 230), (400, 280),
(350, 250), (300, 280), (320, 230), (280, 200), (330, 200)]
draw.polygon(star, fill="red")
6. arc() / chord() / pieslice() —— 弧、弦、扇形
bbox = [100, 100, 300, 300]
draw.arc(bbox, start=0, end=90, fill="blue", width=5) # 弧线
draw.chord(bbox, start=0, end=90, fill="lightblue") # 弦
draw.pieslice(bbox, start=0, end=90, fill="cyan") # 扇形
7. point() —— 画点
# 单个点
draw.point((500, 500), fill="red")
# 多个点
draw.point([(510,510), (520,520), (530,530)], fill="green")
5. 颜色格式
| 格式 | 示例 |
|---|---|
| 名称 | "red", "white" |
| 十六进制 | "#FF0000", "#FFFFFF80"(带透明) |
| RGB 元组 | (255, 0, 0) |
| RGBA 元组 | (255, 0, 0, 128)(半透明) |
透明度:仅在
RGBA模式下生效
6. 高级技巧
1. 绘制带透明度的图形
img = Image.new("RGBA", (600, 400), (255,255,255,0))
draw = ImageDraw.Draw(img)
# 半透明矩形
draw.rectangle([50, 50, 250, 150], fill=(255, 0, 0, 128)) # 红色半透明
2. 文字描边(模拟粗体)
def draw_text_with_stroke(draw, xy, text, font, fill, stroke_width=2, stroke_fill="black"):
x, y = xy
# 描边
for adj in range(-stroke_width, stroke_width+1):
draw.text((x+adj, y), text, font=font, fill=stroke_fill)
draw.text((x, y+adj), text, font=font, fill=stroke_fill)
# 主文字
draw.text(xy, text, font=font, fill=fill)
# 使用
draw_text_with_stroke(draw, (100, 100), "描边文字", font, "white", stroke_width=3, stroke_fill="black")
3. 绘制网格
def draw_grid(draw, size, step=50, color="lightgray"):
w, h = size
for x in range(0, w, step):
draw.line([(x, 0), (x, h)], fill=color)
for y in range(0, h, step):
draw.line([(0, y), (w, y)], fill=color)
draw_grid(draw, img.size, 50)
4. 动态生成验证码
import random
def create_captcha():
img = Image.new("RGB", (200, 80), "white")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("arial.ttf", 40)
code = ''.join(random.choices("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", k=4))
for i, c in enumerate(code):
x = 20 + i * 45 + random.randint(-10, 10)
y = 10 + random.randint(-10, 10)
draw.text((x, y), c, font=font, fill=(random.randint(0,100),)*3)
# 干扰线
for _ in range(20):
draw.line([
random.randint(0,200), random.randint(0,80),
random.randint(0,200), random.randint(0,80)
], fill=(150,150,150), width=1)
return img, code
captcha, text = create_captcha()
captcha.save("captcha.png")
print("验证码:", text)
7. 完整示例:专业水印工具
from PIL import Image, ImageDraw, ImageFont
def add_pro_watermark(input_path, output_path, text="© 2025 摄影师张三"):
img = Image.open(input_path).convert("RGBA")
draw = ImageDraw.Draw(img)
# 字体
try:
font = ImageFont.truetype("simhei.ttf", 36)
except:
font = ImageFont.load_default()
# 计算文字大小
bbox = draw.textbbox((0,0), text, font=font)
w = bbox[2] - bbox[0]
h = bbox[3] - bbox[1]
# 位置:右下角
x = img.width - w - 20
y = img.height - h - 20
# 阴影
draw.text((x+2, y+2), text, font=font, fill=(0,0,0,100))
# 主文字(半透明白)
draw.text((x, y), text, font=font, fill=(255,255,255,180))
img.convert("RGB").save(output_path, quality=95)
print("水印添加完成!")
# 使用
add_pro_watermark("photo.jpg", "watermarked.jpg")
8. 官方文档
ImageDraw 方法速查卡
draw = ImageDraw.Draw(img)
draw.text((x,y), "文字", font=font, fill="red")
draw.line([(x1,y1),(x2,y2)], fill="blue", width=3)
draw.rectangle([x1,y1,x2,y2], fill="yellow", outline="black", width=2)
draw.ellipse([x1,y1,x2,y2], fill="green")
draw.polygon([(x1,y1),(x2,y2),(x3,y3)], fill="purple")
draw.rounded_rectangle([x1,y1,x2,y2], radius=20, fill="pink")
一句话总结
ImageDraw= Pillow 的画笔
文字、图形、标注、水印、验证码 → 全靠它!
需要我为你生成:
- ImageDraw 绘图模板库(矩形、圆形、箭头、标注框)
- GUI 绘图工具(用
tkinter) - 批量加水印命令行工具
欢迎继续提问!