2009-12-15 13 views
7

Come tagliare l'area del bordo vuoto di un'immagine PNG e ridurla alla sua dimensione minima usando Python?Ritaglia un'immagine PNG alle dimensioni minime

+0

La dimensione dell'area di confine è statica? In tal caso, puoi provare a utilizzare i collegamenti Python di ImageMagick. – Qberticus

+0

la dimensione del bordo bianco non è un valore fisso, varia a seconda dell'immagine. – jack

risposta

13

PIL s' getbbox sta lavorando per me

im.getbbox() => 4 parametri o Nessuno

Calcola il rettangolo di selezione dei diverse da zero regioni nell'immagine. La casella di delimitazione viene restituita come una tupla di 4 che definisce la coordinata di pixel inferiore sinistra, superiore, destra e . Se l'immagine è completamente vuota, questo metodo restituisce Nessuno.

Esempio di codice che ho provato, ho provato con bmp, ma dovrebbe funzionare anche per 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

È possibile utilizzare PIL per trovare righe e colonne dell'immagine composte esclusivamente dal colore del bordo.

Utilizzando queste informazioni, è possibile determinare facilmente le estensioni dell'immagine intarsiata.

PIL di nuovo consentirà quindi di ritagliare l'immagine per rimuovere il bordo.

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

penso che sia necessario integrare la risposta di @Frank Krueger. Fa un buon punto, ma non include come ritagliare correttamente il colore extra del bordo da un'immagine. Ho trovato che here. Nello specifico, ho trovato questo utile:

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

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. - [Dalla revisione] (/ recensione/post di bassa qualità/11453172) – niton

+0

Modificato per includere un codice specifico. Buon punto – AaronJPung

2

Ho avuto lo stesso problema oggi. Ecco la mia soluzione per ritagliare i bordi trasparenti. Basta lanciare questo script nella cartella con i file 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) 
Problemi correlati