有時候我們會希望把一幅白底圖片的“有效部分”裁剪出來,比如網頁截圖時懶得按element截,就可以整個網頁截屏后裁剪一下。思路很簡單:識別出圖片上非白色部分的矩形邊界,然后裁剪。
PIL庫提供了一個getbbox
方法來檢測邊界,可以實現這個操作。
bbox是“有效部分”左、上、右、下邊緣的位置,如下圖。
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