将PNG图像裁剪到最小尺寸
如何用Python去掉PNG图片的空白边框,并把它缩小到最小尺寸?
注意:边框的大小不是固定的,可能会因图片而异。
7 个回答
5
我今天也遇到了同样的问题。这里是我解决透明边框的方法。只需把这个脚本放到你存放批量 .png 文件的文件夹里:
from PIL import Image
import numpy as np
from os import listdir
def crop(png_image_name):
pil_image = Image.open(png_image_name)
np_array = np.array(pil_image)
blank_px = [255, 255, 255, 0]
mask = np_array != blank_px
coords = np.argwhere(mask)
x0, y0, z0 = coords.min(axis=0)
x1, y1, z1 = coords.max(axis=0) + 1
cropped_box = np_array[x0:x1, y0:y1, z0:z1]
pil_image = Image.fromarray(cropped_box, 'RGBA')
print(pil_image.width, pil_image.height)
pil_image.save(png_image_name)
print(png_image_name)
for f in listdir('.'):
if f.endswith('.png'):
crop(f)
7
这里有一个现成的解决方案:
import numpy as np
from PIL import Image
def bbox(im):
a = np.array(im)[:,:,:3] # keep RGB only
m = np.any(a != [255, 255, 255], axis=2)
coords = np.argwhere(m)
y0, x0, y1, x1 = *np.min(coords, axis=0), *np.max(coords, axis=0)
return (x0, y0, x1+1, y1+1)
im = Image.open('test.png')
print(bbox(im)) # (33, 12, 223, 80)
im2 = im.crop(bbox(im))
im2.save('test_cropped.png')
示例输入(如果你想试试,可以点击下载链接):
输出结果:
46
im.getbbox() => 4元组或None
这个方法用来计算图像中非零区域的边界框。边界框会以一个4元组的形式返回,分别表示左、上、右和下的像素坐标。如果图像完全为空,这个方法会返回None。
我尝试的代码示例,我用bmp格式测试过,但应该也适用于png格式。
import Image
im = Image.open("test.bmp")
im.size # (364, 471)
im.getbbox() # (64, 89, 278, 267)
im2 = im.crop(im.getbbox())
im2.size # (214, 178)
im2.save("test2.bmp")