有时候我们会希望把一幅白底图片的“有效部分”裁剪出来,比如网页截图时懒得按element截,就可以整个网页截屏后裁剪一下。思路很简单:识别出图片上非白色部分的矩形边界,然后裁剪。
PIL库提供了一个getbbox
方法来检测边界,可以实现这个操作。
bbox是“有效部分”左、上、右、下边缘的位置,如下图。
代码示例:
from io import BytesIO
from PIL import Image, ImageOps
def crop_margin(img_fileobj, padding=(0, 0, 0, 0)):
# 我们不一定需要把图片真的保存成一个文件再打开来裁剪
# img_fileobj泛指一个类文件对象,比如BytesIO就可以
# 本方法传入img_fileobj,返回裁剪后图片的字节流
with BytesIO('') as output_bf:
# 转换成RGB格式,然后运用getbbox方法
image = Image.open(img_fileobj).convert('RGB')
# getbbox实际上检测的是黑边,所以要先将image对象反色
ivt_image = ImageOps.invert(image)
# 如果担心检测出来的bbox过小,可以加点padding
bbox = ivt_image.getbbox()
left = bbox[0] - padding[0]
top = bbox[1] - padding[1]
right = bbox[2] + padding[2]
bottom = bbox[3] + padding[3]
cropped_image = image.crop([left, top, right, bottom])
cropped_image.save(output_bf, format='PNG')
# 取出字节流作为返回值,用于保存文件或直接传输都可以
ret = output_bf.getvalue()
return ret