【问题标题】:Python: PIL replace a single RGBA colorPython:PIL 替换单个 RGBA 颜色
【发布时间】:2010-09-20 14:37:19
【问题描述】:

我已经看过这个问题:SO question 并且似乎已经实现了一种非常相似的技术来替换包括 alpha 值的单一颜色:

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。所以我的起始图像和结果图像看起来像这样,左侧是我的起始图像,右侧是我的结束图像(注意:背景已更改为浅灰色,因此您可以看到它,因为它实际上是透明的,您不会看不到左边的点。)

有更好的方法吗?

【问题讨论】:

    标签: python colors python-imaging-library


    【解决方案1】:

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

    编辑:这是一个缓慢的星期一,所以我想我会添加几个例子:

    只是为了表明它不考虑 alpha 值,以下是示例图像的一个版本的结果,其中一个径向渐变应用于 alpha 通道:

    原文:

    结果:

    【讨论】:

    • 太棒了!惊人的!惊人的! +1 并标记为“已接受”。节省大量时间,结果完美。
    • 不应该,红绿蓝? white_areas =
    • data[..., :-1][white_areas] = (255, 0, 0) IndexError: index 49 is out of bounds for axis 0 with size 40
    • 与 Sekai 类似的错误:/ IndexError: index 200 is out of bounds for axis 0 with size 200
    • 我没有得到 data[... 的部分。 ... 应该是什么意思?
    【解决方案2】:

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

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

    您可以在 gimp 中使用颜色选择器来吸收颜色并查看那是 rgba 颜色

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2012-07-07
        • 2011-01-04
        • 2011-10-11
        • 2021-01-27
        • 1970-01-01
        • 2015-05-19
        • 1970-01-01
        • 2014-12-06
        相关资源
        最近更新 更多