2012-05-16 13 views
30

Esiste una soluzione semplice per ritagliare gli spazi bianchi sull'immagine in PIL?Spazio vuoto di ritaglio con PIL

ImageMagick ha un facile supporto per esso in modo seguente:

convert test.jpeg -fuzz 7% -trim test_trimmed.jpeg 

ho trovato una soluzione per il PIL:

from PIL import Image, ImageChops 

def trim(im, border): 
    bg = Image.new(im.mode, im.size, border) 
    diff = ImageChops.difference(im, bg) 
    bbox = diff.getbbox() 
    if bbox: 
     return im.crop(bbox) 

Ma questa soluzione ha degli svantaggi:

  1. ho bisogno di definire il colore border, non è un grosso problema per me, le mie immagini hanno lo sfondo bianco
  2. E il più svantaggio, questa soluzione PIL non supporta la chiave -fuzz di ImageMagick. Per aggiungere qualche ritaglio sfocato. come posso avere alcuni artefatti di compressione jpeg e ombre enormi non necessarie.

Può essere che il PIL abbia alcune funzioni incorporate per esso? Oppure c'è qualche soluzione veloce?

+1

So che il codice è esattamente lo stesso lì, ma può anche essere trovato qui - https://gist.github.com/mattjmorrison/932345 –

risposta

74

Non credo che ci sia qualcosa di costruito nel PIL che possa farlo. Ma ho modificato il tuo codice in modo che lo faccia.

  • Ottiene il colore del bordo dal pixel in alto a sinistra, utilizzando getpixel, quindi non è necessario passare il colore.
  • Sottrae uno scalare dall'immagine differita, questo è un modo rapido per saturare tutti i valori sotto 100, 100, 100 (nel mio esempio) a zero. Quindi è un modo pulito per rimuovere qualsiasi "oscillazione" risultante dalla compressione.

Codice:

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

jpeg fortemente compresso:

enter image description here ritagliata: enter image description here

jpeg Noisy:

enter image description here ritagliata: enter image description here

+4

Questo è stato io sto cercando. Funziona come una magia. Grazie. –

+0

@Ideviantik - cool, l'ho leggermente semplificato. godere. – fraxel

+5

Nota che l'operazione che stai facendo è molto pericolosa: compensa il rumore nel bordo, ma non puoi più gestire le immagini in cui lo sfondo e l'immagine stessa sono molto simili - per esempio le foto se gli articoli bianchi sono posizionati su uno sfondo bianco. –

1

utilizzando la funzione di assetto nel modulo ufp.image.

import ufp.image 
import PIL 
im = PIL.Image.open('test.jpg', 'r') 
trimed = ufp.image.trim(im, fuzz=13.3) 
trimed.save('trimed.jpg') 

vedere Esempio: Trim image edge whitespace with fuzz [Python]

+1

Questo link nella tua risposta ora inoltra a un download di file da 1 GB. Potrebbe essere una buona idea rimuoverlo. –

Problemi correlati