将PNG图像裁剪为最小尺寸

时间:2009-12-15 05:52:01

标签: python image png

如何切断PNG图像的空白边框区域并使用Python将其缩小到最小尺寸?

6 个答案:

答案 0 :(得分:16)

PILgetbbox正在为我工​​作

  

im.getbbox()=> 4元组或无

     

计算的边界框   图像中的非零区域。该   边界框作为4元组返回   定义左,上,右和   较低的像素坐标。如果是图像   完全是空的,这个方法   返回无。

我试过的代码示例,我已经使用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")

答案 1 :(得分:3)

https://gist.github.com/3141140

import Image
import sys
import glob

# Trim all png images with alpha in a folder
# Usage "python PNGAlphaTrim.py ../someFolder"

try:
    folderName = sys.argv[1]
except :
    print "Usage: python PNGPNGAlphaTrim.py ../someFolder"
    sys.exit(1)

filePaths = glob.glob(folderName + "/*.png") #search for all png images in the folder

for filePath in filePaths:
    image=Image.open(filePath)
    image.load()

    imageSize = image.size
    imageBox = image.getbbox()

    imageComponents = image.split()

    if len(imageComponents) < 4: continue #don't process images without alpha

    rgbImage = Image.new("RGB", imageSize, (0,0,0))
    rgbImage.paste(image, mask=imageComponents[3])
    croppedBox = rgbImage.getbbox()

    if imageBox != croppedBox:
        cropped=image.crop(croppedBox)
        print filePath, "Size:", imageSize, "New Size:",croppedBox
        cropped.save(filePath)

答案 2 :(得分:3)

我今天遇到了同样的问题。这是我解决透明边框的方法。只需将此脚本与批量.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)

答案 3 :(得分:1)

您可以使用PIL查找纯粹由边框颜色组成的图像行和列。

使用此信息,您可以轻松确定镶嵌图像的范围。

PIL将再次允许您裁剪图像以删除边框。

答案 4 :(得分:0)

我认为有必要补充@Frank Krueger的回答。他提出了一个很好的观点,但它没有包括如何从图像中正确地裁剪出额外的边框颜色。我发现here。具体来说,我觉得这很有用:

from PIL import Image, ImageChops

def trim(im):
    bg = Image.new(im.mode, im.size, im.getpixel((0,0)))
    diff = ImageChops.difference(im, bg)
    diff = ImageChops.add(diff, diff, 2.0, -100)
    bbox = diff.getbbox()
    if bbox:
        return im.crop(bbox)

im = Image.open("bord3.jpg")
im = trim(im)
im.show()

答案 5 :(得分:0)

以下是现成的解决方案:

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')

示例输入({download link,如果您想尝试):

enter image description here

输出:

enter image description here