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. 官方文档

https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html

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
  • 批量加水印命令行工具

欢迎继续提问!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注