代码之家  ›  专栏  ›  技术社区  ›  sberry

Python:PIL替换单个RGBA颜色

  •  16
  • sberry  · 技术社区  · 14 年前

    SO question

    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                                                                                                   
    

    然而,这是非常缓慢的。我发现 this recipe 但到目前为止还没有成功地使用它。

    我想做的是采取各种PNG图像,其中包括一个单一的颜色,白色。每个像素都是100%白色,具有各种alpha值,包括alpha=0。我要做的基本上是用一个新的设置颜色给图像上色,例如#ff0000<00ff>。所以我的开始图像和结果图像看起来是这样的,左边是我的开始图像,右边是我的结束图像(注意:背景已经变为浅灰色,所以你可以看到它,因为它实际上是透明的,你不能看到左边的点。)

    alt text

    有更好的办法吗?

    3 回复  |  直到 5 年前
        1
  •  59
  •   jucor Joe Kington    9 年前

    如果你有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

        2
  •  7
  •   Yuda Prawira David Dehghan    14 年前

    试试这个,在这个示例中,如果颜色不是白色,我们将颜色设置为黑色。

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

        3
  •  3
  •   Jonathan Root Josep Valls    11 年前

    Pythonware PIL在线图书章节 Image module 规定putpixel()的速度很慢,并建议可以通过内联来加快速度。或者根据PIL版本,改用load()。