2010-09-20 6 views
13

Je l'ai déjà pris un coup d'œil à cette question: SO question et semblent avoir mis en œuvre une technique très similaire pour le remplacement d'une seule couleur, y compris les valeurs alpha:Python: PIL remplacer une seule couleur RGBA

c = Image.open(f) 
c = c.convert("RGBA") 
w, h = c.size 
cnt = 0 
for px in c.getdata(): 
    c.putpixel((int(cnt % w), int(cnt/w)), (255, 0, 0, px[3]))                          cnt += 1 

Cependant, c'est très lent. J'ai trouvé cette recette sur les interwebs, mais n'ai pas réussi à l'utiliser jusqu'ici: recipe

Ce que j'essaie de faire est de prendre diverses images PNG qui consistent en une seule couleur, blanc. Chaque pixel est 100% blanc avec différentes valeurs alpha, y compris alpha = 0. Ce que je veux faire est essentiellement coloriser l'image avec une nouvelle couleur de jeu, par exemple # FF0000 < 00-ff>. Donc, mon départ et les images résultantes ressemblerait à ceci où le côté gauche est mon image de départ et le droit est mon image (NOTE fin fond a été changé à un gris clair pour que vous puissiez le voir car il est réellement transparent et vous n » t être en mesure de voir les points à gauche.)

alt text

une meilleure façon de le faire?

Répondre

32

Si vous avez numpy, il fournit beaucoup, beaucoup plus rapide pour fonctionner sur les images LIP.

Par exemple:

import Image 
import numpy as np 

im = Image.open('test.png') 
im = im.convert('RGBA') 

data = np.array(im) # "data" is a height x width x 4 numpy array 
red, green, blue, alpha = data.T # Temporarily unpack the bands for readability 

# Replace white with red... (leaves alpha values alone...) 
white_areas = (red == 255) & (blue == 255) & (green == 255) 
data[..., :-1][white_areas.T] = (255, 0, 0) # Transpose back needed 

im2 = Image.fromarray(data) 
im2.show() 

Edit: Il est un lundi lent, donc je me suis dit que je voudrais ajouter quelques exemples:

Juste pour montrer qu'il est en laissant les valeurs alpha seul, voici les résultats pour une version de l'image d'exemple avec un gradient radial appliqué sur le canal alpha:

origine: alt text

Résultat: alt text

+1

Impressionnant! Impressionnant! Impressionnant! +1 et marqué comme "Accepté". Le gain de temps énorme et les résultats sont parfaits. – sberry

+0

@sberry - Heureux d'aider! –

+0

ne devrait pas être, Red Green Blue? white_areas = – Sekai

2

Le chapitre de livre en ligne Pythonware PIL pour le Image module stipule que putpixel() est lent et suggère qu'il peut être accéléré par l'inline. Ou en fonction de la version PIL, en utilisant load() à la place.

2

Essayez ceci, dans cet exemple nous avons mis la couleur au noir si la couleur est pas blanc.

#!/usr/bin/python 
from PIL import Image 
import sys 

img = Image.open(sys.argv[1]) 
img = img.convert("RGBA") 

pixdata = img.load() 

# Clean the background noise, if color != white, then set to black. 

for y in xrange(img.size[1]): 
    for x in xrange(img.size[0]): 
     if pixdata[x, y] == (255, 255, 255, 255): 
      pixdata[x, y] = (0, 0, 0, 255) 

vous pouvez utiliser sélecteur de couleur dans gimp pour absorber la couleur et de voir que la couleur est rgba

Questions connexes