86

Python Image Library を使用して、すべての白いピクセルを透明にしようとしています。(私はPythonを学ぼうとしているCハッカーなので、優しくしてください)変換が機能しています(少なくともピクセル値は正しいように見えます)が、リストをバッファに変換して再作成する方法がわかりません画像。これがコードです

img = Image.open('img.png')
imga = img.convert("RGBA")
datas = imga.getdata()

newData = list()
for item in datas:
    if item[0] == 255 and item[1] == 255 and item[2] == 255:
        newData.append([255, 255, 255, 0])
    else:
        newData.append(item)

imgb = Image.frombuffer("RGBA", imga.size, newData, "raw", "RGBA", 0, 1)
imgb.save("img2.png", "PNG")
4

10 に答える 10

112

次の変更を行う必要があります。

  • (255, 255, 255, 0)リストではなくタプルを追加する[255, 255, 255, 0]
  • 使用するimg.putdata(newData)

これは作業コードです:

from PIL import Image

img = Image.open('img.png')
img = img.convert("RGBA")
datas = img.getdata()

newData = []
for item in datas:
    if item[0] == 255 and item[1] == 255 and item[2] == 255:
        newData.append((255, 255, 255, 0))
    else:
        newData.append(item)

img.putdata(newData)
img.save("img2.png", "PNG")
于 2009-04-19T17:38:26.280 に答える
51

ピクセル アクセス モードを使用して、画像をその場で変更することもできます。

from PIL import Image

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

pixdata = img.load()

width, height = img.size
for y in range(height):
    for x in range(width):
        if pixdata[x, y] == (255, 255, 255, 255):
            pixdata[x, y] = (255, 255, 255, 0)

img.save("img2.png", "PNG")

頻繁に使用する場合は、上記をスクリプトにラップすることもできます。

于 2009-04-19T18:17:14.207 に答える
9

これは現在、「Pillow white to transparent」を探している最初の Google の結果であるため、同じことが numpy で達成できることを追加したいと思います。 10 倍高速です (提案されたソリューションの 3.28 秒に対して約 300 ミリ秒)。コードも少し短くなります。

import numpy as np

def white_to_transparency(img):
    x = np.asarray(img.convert('RGBA')).copy()

    x[:, :, 3] = (255 * (x[:, :, :3] != 255).any(axis=2)).astype(np.uint8)

    return Image.fromarray(x)

また、「ほぼ白」(たとえば、1 つのチャネルが 255 ではなく 254) が「ほぼ透明」なバージョンに簡単に交換できます。もちろん、これにより、純粋な黒を除いて、画像全体が部分的に透明になります。

def white_to_transparency_gradient(img):
    x = np.asarray(img.convert('RGBA')).copy()

    x[:, :, 3] = (255 - x[:, :, :3].mean(axis=2)).astype(np.uint8)

    return Image.fromarray(x)

注:.copy()デフォルトでは、Pillow イメージは読み取り専用配列に変換されるため、 が必要です。

于 2019-01-11T14:24:35.080 に答える
8
import Image
import ImageMath

def distance2(a, b):
    return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) + (a[2] - b[2]) * (a[2] - b[2])

def makeColorTransparent(image, color, thresh2=0):
    image = image.convert("RGBA")
    red, green, blue, alpha = image.split()
    image.putalpha(ImageMath.eval("""convert(((((t - d(c, (r, g, b))) >> 31) + 1) ^ 1) * a, 'L')""",
        t=thresh2, d=distance2, c=color, r=red, g=green, b=blue, a=alpha))
    return image

if __name__ == '__main__':
    import sys
    makeColorTransparent(Image.open(sys.argv[1]), (255, 255, 255)).save(sys.argv[2]);
于 2010-12-25T19:34:34.070 に答える
4

大きな画像の場合、ループには非常に長い時間がかかるため、より Pythonic な方法

from PIL import Image

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

imgnp = np.array(img)

white = np.sum(imgnp[:,:,:3], axis=2)
white_mask = np.where(white == 255*3, 1, 0)

alpha = np.where(white_mask, 0, imgnp[:,:,-1])

imgnp[:,:,-1] = alpha 

img = Image.fromarray(np.uint8(imgnp))
img.save("img2.png", "PNG")
于 2020-09-15T10:32:01.190 に答える