2009-12-15 16 views
7

Cómo cortar el área de borde en blanco de una imagen PNG y reducirla a su tamaño mínimo con Python?Recortar una imagen PNG a su tamaño mínimo

+0

¿Está el tamaño del área del borde estático? Si es así, puede intentar usar enlaces de python ImageMagick. – Qberticus

+0

el tamaño del borde en blanco no es un valor fijo, varía según la imagen. – jack

Respuesta

13

PIL 's getbbox está trabajando para mí

im.getbbox() => 4-tupla o Ninguno

Calcula el cuadro delimitador de las no nulos regiones en la imagen. El cuadro delimitador se devuelve como un 4-tuple que define la coordenada inferior del píxel izquierdo, superior, derecho y . Si la imagen está completamente vacía, este método devuelve None.

Código Muestra que probé, lo he probado con bmp, pero debería funcionar también para 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

Puede usar PIL para buscar las filas y columnas de su imagen que están formadas únicamente por el color de su borde.

Al usar esta información, puede determinar fácilmente la extensión de la imagen incrustada.

PIL nuevamente le permitirá recortar la imagen para eliminar el borde.

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

creo que es necesario complementar la respuesta de @Frank Krueger. Él hace un buen punto, pero no incluye cómo recortar adecuadamente el color del borde extra de una imagen. Encontré que here. Específicamente, encontré esto útil:

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() 
+0

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. - [De la crítica] (/ review/low-quality-posts/11453172) – niton

+0

Editado para incluir código específico. Buen punto. – AaronJPung

2

Tuve el mismo problema hoy. Aquí está mi solución para recortar los bordes transparentes. Simplemente coloque este script en su carpeta con sus archivos batch .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) 
Cuestiones relacionadas