2012-07-14 70 views
5

Ho un set di icone bianche su sfondo trasparente, e vorrei invertirle tutte per essere nere su sfondo trasparente.Python: immagine invertita con sfondo trasparente (PIL, Gimp, ...)

enter image description here

hanno provato con pil (ImageChops), ma non sembra di lavorare con sfondi trasparenti. Ho anche provato l'interfaccia Python di Gimp, ma senza fortuna neanche lì.

Qualche idea su come sia possibile ottenere l'inversione in Python?

+0

Quale formato sono le immagini? – Acorn

+0

il loro formato file è png – Hoff

risposta

5

ImageChops.invert sembra anche invertire il canale alfa di ciascun pixel.

Questo dovrebbe fare il lavoro:

import Image 

img = Image.open('image.png').convert('RGBA') 

r, g, b, a = img.split() 

def invert(image): 
    return image.point(lambda p: 255 - p) 

r, g, b = map(invert, (r, g, b)) 

img2 = Image.merge(img.mode, (r, g, b, a)) 

img2.save('image2.png') 
+0

Invece di definire il proprio 'invert()' potreste semplicemente usare 'ImageOps.invert()' su ogni canale poiché ogni canale ha tipo '" L "'. (o suppongo 'ImageChops.invert()' ma non l'ho mai provato io stesso). – Ray

1

Ho provato l'approccio di Acorn, ma il risultato è un po 'strano (parte superiore dell'immagine qui sotto).

enter image description here

L'icona di fondo è quello che volevo veramente, ho raggiunto esso utilizzando Image Magick 's convertono metodo:

convert tools.png -negate tools_black.png

(non python per sé, ma esistono involucri pitone, come PythonMagickWand

L'unico inconveniente è che è necessario installare un mucchio di dipendenze per far funzionare ImageMagick, ma sembra essere una potente immagine quadro di pulitura.

+0

A destra, il codice che ho postato stava solo convertendo i pixel bianchi in nero. Ho aggiornato la mia risposta con un'inversione generica. – Acorn

0

Lo si può fare abbastanza facilmente con PIL, in questo modo:

  1. Assicurarsi che l'immagine viene rappresentata come RGBA, utilizzando convert('RGBA').
  2. Divide l'immagine in bande RGBA separate.
  3. Fai ciò che vuoi sulle bande RGB (nel tuo caso le impostiamo tutte in nero usando la funzione point), ma non toccare la banda alfa.
  4. Unire le bande indietro.

Heres il codice:

import Image 
im = Image.open('image.png') 
im = im.convert('RGBA') 
r, g, b, a = im.split() 
r = g = b = r.point(lambda i: 0) 
im = Image.merge('RGBA', (r, g, b, a)) 
im.save('saved.png') 

dare un colpo.

0
import Image, numpy 
pixels = numpy.array(Image.open('myimage.png')) 
pixels[:,:,0:3] = 255 - pixels[:,:,0:3] # invert 
Image.fromarray(pixels).save('out.png') 

Probabilmente la soluzione più veloce finora, dal momento che non interpreta alcun codice Python all'interno di un "per ogni pixel" loop.