web-dev-qa-db-ja.com

Python:PILが単一のRGBAカラーを置き換える

私はすでにこの質問を調べました: SO質問 で、アルファ値を含む単一の色を置き換えるための非常に類似した手法を実装しているようです:

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                                                                                                   

ただし、これは非常に低速です。私は このレシピ をインターウェブで見つけましたが、これまでこれを使用することに成功していません。

私がやろうとしていることは、単色の白で構成されるさまざまなPNG画像を撮ることです。各ピクセルは100%白で、アルファ= 0を含むさまざまなアルファ値が含まれています。基本的には、たとえば#ff0000 <00-ff>などの新しい設定色で画像に色を付けます。 SO私の開始および結果の画像は、左側が開始画像で、右側が終了画像です(注:背景が薄いグレーに変更されているので、見やすくなっています)実際には透明で、左側のドットが見えないためです。)

alt text

これを行うより良い方法はありますか?

23
sberry

Numpyがある場合は、PILイメージを操作するためのはるかに高速な方法を提供します。

例えば。:

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

編集:遅い月曜日なので、いくつかの例を追加すると思いました。

アルファ値のみを残していることを示すために、アルファチャネルに放射状グラデーションが適用されたサンプル画像のバージョンの結果を次に示します。

元の: alt text

結果: alt text

53
Joe Kington

これを試してください。このサンプルでは、​​色が白でない場合、色を黒に設定します。

#!/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)

ギンプのカラーピッカーを使用して色を吸収し、それがRGBAカラーであることを確認できます

6
Yuda Prawira

Image module のPythonware PILオンラインブックの章では、putpixel()が遅いことを規定し、インライン化することで高速化できることを示唆しています。または、PILバージョンに応じて、代わりにload()を使用します。

3
T.P.