本文目录导读:

我来分享几个Python图片裁剪的实用案例,使用最常用的PIL库。
基础矩形裁剪
from PIL import Image
import os
# 打开图片
img = Image.open('input.jpg')
# 定义裁剪区域 (left, upper, right, lower)
# 左上角为(0,0),right和lower是结束坐标
crop_area = (100, 50, 400, 300) # 左、上、右、下
# 执行裁剪
cropped_img = img.crop(crop_area)
# 保存结果
cropped_img.save('cropped.jpg')
print(f"原图尺寸: {img.size}")
print(f"裁剪后尺寸: {cropped_img.size}")
中心裁剪(正方形)
def center_crop_square(image_path, output_path):
"""从图片中心裁剪出最大的正方形"""
img = Image.open(image_path)
width, height = img.size
# 计算取最小的边长
min_side = min(width, height)
# 计算裁剪区域(居中)
left = (width - min_side) // 2
top = (height - min_side) // 2
right = left + min_side
bottom = top + min_side
# 执行裁剪
cropped = img.crop((left, top, right, bottom))
cropped.save(output_path)
print(f"已从中心裁剪出 {min_side}x{min_side} 的正方形")
# 使用示例
center_crop_square('input.jpg', 'center_square.jpg')
指定比例的裁剪
def crop_to_ratio(image_path, target_ratio, output_path):
"""
按目标比例裁剪图片
target_ratio: 16/9 或 4/3
"""
img = Image.open(image_path)
width, height = img.size
current_ratio = width / height
if current_ratio > target_ratio:
# 图片过宽,裁剪宽度
new_width = int(height * target_ratio)
left = (width - new_width) // 2
crop_box = (left, 0, left + new_width, height)
else:
# 图片过高,裁剪高度
new_height = int(width / target_ratio)
top = (height - new_height) // 2
crop_box = (0, top, width, top + new_height)
cropped = img.crop(crop_box)
cropped.save(output_path)
print(f"已裁剪为 {target_ratio} 比例")
# 裁剪为16:9
crop_to_ratio('input.jpg', 16/9, '16_9_ratio.jpg')
批量裁剪固定区域
def batch_crop_images(input_dir, output_dir, crop_area):
"""批量裁剪指定文件夹中的所有图片"""
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
# 打开图片
img_path = os.path.join(input_dir, filename)
img = Image.open(img_path)
# 裁剪
cropped = img.crop(crop_area)
# 保存
output_path = os.path.join(output_dir, f'cropped_{filename}')
cropped.save(output_path)
print(f"已处理: {filename}")
# 使用示例:裁剪所有图片的左上角300x300区域
crop_area = (0, 0, 300, 300)
batch_crop_images('input_folder', 'output_folder', crop_area)
九宫格裁剪
def nine_grid_crop(image_path, output_dir):
"""将图片裁剪为3x3的九宫格"""
img = Image.open(image_path)
width, height = img.size
# 计算每个小格子的尺寸
w_third = width // 3
h_third = height // 3
os.makedirs(output_dir, exist_ok=True)
# 遍历九宫格
for row in range(3):
for col in range(3):
left = col * w_third
upper = row * h_third
right = left + w_third
lower = upper + h_third
# 裁剪并保存
cell = img.crop((left, upper, right, lower))
cell.save(f'{output_dir}/cell_{row}_{col}.jpg')
print("九宫格裁剪完成!")
# 使用示例
nine_grid_crop('input.jpg', 'nine_grid_output')
交互式裁剪(手动选择区域)
import matplotlib.pyplot as plt
from matplotlib.widgets import RectangleSelector
def interactive_crop(image_path):
"""交互式选择裁剪区域"""
img = Image.open(image_path)
fig, ax = plt.subplots()
ax.imshow(img)
# 存储选择的区域
select_area = []
def onselect(eclick, erelease):
"""选择事件回调"""
x1, y1 = int(eclick.xdata), int(eclick.ydata)
x2, y2 = int(erelease.xdata), int(erelease.ydata)
# 确保坐标顺序正确
left = min(x1, x2)
right = max(x1, x2)
top = min(y1, y2)
bottom = max(y1, y2)
select_area.clear()
select_area.extend([left, top, right, bottom])
print(f"选择的区域: {select_area}")
# 创建矩形选择器
rs = RectangleSelector(ax, onselect, drawtype='box')
plt.title("拖动鼠标选择要裁剪的区域")
plt.show()
# 如果选择了区域,进行裁剪
if select_area:
cropped = img.crop(tuple(select_area))
cropped.save('interactive_cropped.jpg')
print("裁剪完成!")
# 注意:这个需要手动关闭图片窗口
# interactive_crop('input.jpg')
安装依赖
pip install Pillow matplotlib
实用技巧
# 1. 保持原图比例裁剪
def smart_crop(image, target_size):
"""智能裁剪到目标尺寸"""
img = Image.open(image)
img.thumbnail(target_size, Image.Resampling.LANCZOS)
# 创建新背景
new_img = Image.new('RGB', target_size, (255, 255, 255))
# 居中放置
x = (target_size[0] - img.width) // 2
y = (target_size[1] - img.height) // 2
new_img.paste(img, (x, y))
return new_img
# 2. 检测并裁剪空白区域
def crop_whitespace(image_path, threshold=240):
"""裁剪图片边缘的空白区域"""
img = Image.open(image_path).convert('L') # 转为灰度图
import numpy as np
img_array = np.array(img)
# 找出非空白区域
non_white = np.where(img_array < threshold)
if non_white[0].size > 0: # 如果有非空白区域
top = non_white[0].min()
bottom = non_white[0].max()
left = non_white[1].min()
right = non_white[1].max()
# 裁剪
original = Image.open(image_path)
cropped = original.crop((left, top, right + 1, bottom + 1))
return cropped
return Image.open(image_path)
这些案例涵盖了常见的裁剪需求,你可以根据具体情况选择合适的方案。