本文目录导读:

我来介绍如何使用Pillow库绘制几何图形,包含多个实用的案例。
安装Pillow
pip install Pillow
基础案例:绘制基本几何图形
from PIL import Image, ImageDraw, ImageFont
# 创建一个新图像
width, height = 500, 400
image = Image.new('RGB', (width, height), (255, 255, 255))
draw = ImageDraw.Draw(image)
# 1. 绘制直线
draw.line([(50, 50), (200, 50)], fill='red', width=3)
draw.line([(50, 50), (50, 200)], fill='blue', width=3)
# 2. 绘制矩形
draw.rectangle([(250, 50), (400, 150)], fill='yellow', outline='black', width=2)
# 3. 绘制圆角矩形
draw.rounded_rectangle([(50, 250), (200, 350)], radius=20, fill='lightblue', outline='blue', width=2)
# 4. 绘制椭圆/圆
draw.ellipse([(250, 250), (400, 350)], fill='lightgreen', outline='green', width=2)
# 5. 绘制多边形(三角形)
draw.polygon([(400, 50), (450, 150), (350, 150)], fill='orange', outline='red', width=2)
# 6. 绘制扇形(饼图切片)
draw.pieslice([(300, 200), (450, 350)], start=-30, end=120, fill='pink', outline='purple', width=2)
# 7. 绘制弧线
draw.arc([(50, 50), (200, 200)], start=0, end=180, fill='darkblue', width=3)
# 8. 绘制弦(弧的端点相连)
draw.chord([(150, 50), (300, 200)], start=0, end=180, fill='lightcoral', outline='red', width=2)
# 9. 绘制点
for i in range(5, 50, 10):
draw.point([(i, 300)], fill='purple')
image.save('basic_shapes.png')
image.show()
中级案例:绘制棋盘格
from PIL import Image, ImageDraw
def draw_chessboard(size=8, cell_size=50):
# 计算图像大小
img_size = size * cell_size
image = Image.new('RGB', (img_size, img_size), (255, 255, 255))
draw = ImageDraw.Draw(image)
# 绘制棋盘格
for row in range(size):
for col in range(size):
x0 = col * cell_size
y0 = row * cell_size
x1 = x0 + cell_size
y1 = y0 + cell_size
# 交替颜色
if (row + col) % 2 == 0:
draw.rectangle([x0, y0, x1, y1], fill=(238, 238, 210)) # 浅色
else:
draw.rectangle([x0, y0, x1, y1], fill=(139, 90, 43)) # 深色
return image
# 生成棋盘格
chessboard = draw_chessboard(8, 60)
chessboard.save('chessboard.png')
chessboard.show()
高级案例:绘制雷达图
from PIL import Image, ImageDraw
import math
def draw_radar_chart(data, labels, size=400):
image = Image.new('RGB', (size, size), (255, 255, 255))
draw = ImageDraw.Draw(image)
center_x = center_y = size // 2
radius = size // 2 - 20
# 数据点数
n = len(data)
angle_step = 2 * math.pi / n
# 绘制网格线
for i in range(1, 6):
r = radius * i / 5
points = []
for j in range(n):
angle = -math.pi/2 + j * angle_step # 从顶部开始
x = center_x + r * math.cos(angle)
y = center_y + r * math.sin(angle)
points.append((x, y))
draw.polygon(points, outline='lightgray', width=1)
# 绘制轴标签线
for i in range(n):
angle = -math.pi/2 + i * angle_step
x = center_x + radius * math.cos(angle)
y = center_y + radius * math.sin(angle)
draw.line([(center_x, center_y), (x, y)], fill='gray', width=1)
# 添加标签
label_x = center_x + (radius + 20) * math.cos(angle)
label_y = center_y + (radius + 20) * math.sin(angle)
draw.text((label_x - 20, label_y - 10), labels[i], fill='black')
# 绘制数据
points = []
for i in range(n):
angle = -math.pi/2 + i * angle_step
r = radius * data[i] / 100 # 假设数据是0-100的值
x = center_x + r * math.cos(angle)
y = center_y + r * math.sin(angle)
points.append((x, y))
draw.polygon(points, fill=(100, 200, 100, 80), outline='green', width=2)
return image
# 使用示例:绘制能力雷达图
data = [80, 60, 90, 85, 70, 95, 75] # 各项能力值
labels = ['Python', 'Java', '算法', '数据库', '前端', '网络', '系统管理']
radar = draw_radar_chart(data, labels, 500)
radar.save('radar_chart.png')
radar.show()
实用案例:绘制柱状图
from PIL import Image, ImageDraw
def draw_bar_chart(data, title="柱状图"):
width, height = 600, 400
margin = 80
image = Image.new('RGB', (width, height), (255, 255, 255))
draw = ImageDraw.Draw(image)
# 计算柱状图参数
bar_count = len(data)
bar_width = (width - 2 * margin) // bar_count
max_value = max(data.values()) if data else 1
# 标题
draw.text((width//2 - 50, 10), title, fill='black')
# 绘制坐标轴
draw.line([(margin, height - margin), (width - margin, height - margin)], fill='black', width=2) # X轴
draw.line([(margin, margin), (margin, height - margin)], fill='black', width=2) # Y轴
# 绘制柱子
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8']
for i, (label, value) in enumerate(data.items()):
x0 = margin + i * bar_width + 10
y0 = height - margin - (value / max_value) * (height - 2 * margin)
x1 = x0 + bar_width - 20
y1 = height - margin
# 画柱子
draw.rectangle([x0, y0, x1, y1], fill=colors[i % len(colors)], outline='black')
# 添加数值标签
draw.text((x0 + 5, y0 - 20), str(value), fill='black')
# 添加横轴标签
draw.text((x0 - 5, height - margin + 5), label, fill='black')
return image
# 使用示例
sales_data = {
'一月': 85,
'二月': 120,
'三月': 95,
'四月': 110,
'五月': 130,
'六月': 145
}
chart = draw_bar_chart(sales_data, "月度销售数据")
chart.save('bar_chart.png')
chart.show()
创意案例:绘制雪花图案
from PIL import Image, ImageDraw
import math
def draw_snowflake(size=400, depth=3):
image = Image.new('RGB', (size, size), (20, 30, 50))
draw = ImageDraw.Draw(image)
center = (size // 2, size // 2)
length = size // 3
def draw_branch(start, end, level):
if level == 0:
return
# 绘制主线
draw.line([start, end], fill='white', width=2)
# 计算分支角度
angle = math.atan2(end[1] - start[1], end[0] - start[0])
branch_length = length / (3 - level + 1)
# 绘制分支
for i in [1, -1]: # 左右两个分支
branch_angle = angle + i * math.pi / 3
branch_end = (
end[0] + branch_length * math.cos(branch_angle),
end[1] + branch_length * math.sin(branch_angle)
)
if level > 1:
draw_branch(end, branch_end, level - 1)
else:
draw.line([end, branch_end], fill='white', width=2)
# 生成6个主分支
for i in range(6):
angle = i * math.pi / 3
end = (
center[0] + length * math.cos(angle),
center[1] + length * math.sin(angle)
)
draw_branch(center, end, depth)
# 添加中心装饰
draw.ellipse([center[0]-10, center[1]-10, center[0]+10, center[1]+10],
fill='lightblue', outline='white')
return image
# 生成雪花
snowflake = draw_snowflake(500, 3)
snowflake.save('snowflake.png')
snowflake.show()
综合案例:绘制仪表盘
from PIL import Image, ImageDraw
import math
def draw_gauge(value=75, title="仪表盘"):
size = 300
image = Image.new('RGB', (size, size), (255, 255, 255))
draw = ImageDraw.Draw(image)
center = (size // 2, size // 2)
radius = size // 2 - 30
# 绘制半圆刻度带
for i in range(0, 181, 30):
angle = math.radians(i - 180) # 从左边开始
start_angle = math.radians(i - 180 + 2) # 稍向内偏移
end_angle = math.radians(i - 180 + 28)
# 绘制刻度线
inner_r = radius - 10
outer_r = radius
inner_x = center[0] + inner_r * math.cos(angle)
inner_y = center[1] + inner_r * math.sin(angle)
outer_x = center[0] + outer_r * math.cos(angle)
outer_y = center[1] + outer_r * math.sin(angle)
draw.line([(inner_x, inner_y), (outer_x, outer_y)], fill='blue', width=3)
# 添加刻度标签
label_r = radius + 15
label_x = center[0] + label_r * math.cos(angle)
label_y = center[1] + label_r * math.sin(angle)
draw.text((label_x - 10, label_y - 10), str(i), fill='black')
# 绘制彩色弧度区域
colors = ['green', 'yellow', 'red']
for i, color in enumerate(colors):
start = -180 + i * 60
end = -180 + (i + 1) * 60
draw.arc([center[0]-radius, center[1]-radius,
center[0]+radius, center[1]+radius],
start, end, fill=color, width=5)
# 绘制指针
value_angle = math.radians(value * 180 / 100 - 180)
pointer_length = radius - 20
pointer_x = center[0] + pointer_length * math.cos(value_angle)
pointer_y = center[1] + pointer_length * math.sin(value_angle)
draw.line([center, (pointer_x, pointer_y)], fill='red', width=3)
# 添加中心圆
draw.ellipse([center[0]-8, center[1]-8, center[0]+8, center[1]+8],
fill='darkred')
# 添加标题
draw.text((size//2 - 30, 10), title, fill='black')
return image
# 使用示例
gauge = draw_gauge(65, "CPU使用率")
gauge.save('gauge.png')
gauge.show()
这些案例涵盖了Pillow绘制几何图形的主要功能,从基础到高级,可以应用在各种不同的场景中。