Change specific RGB color pixels to another color, in image file

后端 未结 4 1891
不思量自难忘°
不思量自难忘° 2020-12-06 10:53

I would like to change a single color with Python.

If a fast solution with PIL exists, I would prefer this solution.

At the moment, I use

c         


        
相关标签:
4条回答
  • 2020-12-06 11:37

    If numpy is available on your machine, try doing something like:

    import numpy as np
    from PIL import Image
    
    im = Image.open('fig1.png')
    data = np.array(im)
    
    r1, g1, b1 = 0, 0, 0 # Original value
    r2, g2, b2 = 255, 255, 255 # Value that we want to replace it with
    
    red, green, blue = data[:,:,0], data[:,:,1], data[:,:,2]
    mask = (red == r1) & (green == g1) & (blue == b1)
    data[:,:,:3][mask] = [r2, g2, b2]
    
    im = Image.fromarray(data)
    im.save('fig1_modified.png')
    

    It will use a bit (3x) more memory, but it should be considerably (~5x, but more for bigger images) faster.

    Also note that the code above is slightly more complicated than it needs to be if you only have RGB (and not RGBA) images. However, this example will leave the alpha band alone, whereas a simpler version wouldn't have.

    0 讨论(0)
  • 2020-12-06 11:39

    This is a modification of Joe Kington's answer above. The following is how to do this if your image contains an alpha channel as well.

    import numpy as np
    import Image
    
    im = Image.open('fig1.png')
    im = im.convert('RGBA')
    data = np.array(im)
    
    r1, g1, b1 = 0, 0, 0 # Original value
    r2, g2, b2, a2 = 255, 255, 255, 255 # Value that we want to replace it with
    
    red, green, blue, alpha = data[:,:,0], data[:,:,1], data[:,:,2], data[:,:,3]
    mask = (red == r1) & (green == g1) & (blue == b1)
    data[:,:,:4][mask] = [r2, g2, b2, a2]
    
    im = Image.fromarray(data)
    im.save('fig1_modified.png')
    

    It took me a long time to figure out how to get it to work. I hope that it helps someone else.

    0 讨论(0)
  • 2020-12-06 11:47

    This solution uses glob to edit all pngs in a folder, removing a color and swapping it out with another, but uses RGBA.

    import glob
    from PIL import Image
    
    old_color = 255, 0, 255, 255
    new_color = 0, 0, 0, 0
    
    for path in glob.glob("*.png"):
        if "__out" in path:
            print "skipping on", path
            continue
    
        print "working on", path
    
        im = Image.open(path)
        im = im.convert("RGBA")
        width, height = im.size
        colortuples = im.getcolors()
    
        pix = im.load()
        for x in xrange(0, width):
            for y in xrange(0, height):
                if pix[x,y] == old_color:
                    im.putpixel((x, y), new_color)
    
        im.save(path+"__out.png")
    

    It's a modification of https://stackoverflow.com/a/6483549/541208

    0 讨论(0)
  • 2020-12-06 11:49

    I've just came up with this solution:

    import Image
    im = Image.open("MyImage.png")
    width, height = im.size
    colortuples = im.getcolors()
    mycolor1 = min(colortuples)[1]
    mycolor2 = max(colortuples)[1]
    pix = im.load()
    for x in range(0, width):
        for y in range(0, height):
            if pix[x,y] == mycolor1:
                im.putpixel((x, y), mycolor2)
    im.save('MyImage.png')
    

    Although putpixel isn't fast, it seems to be fast enough for me.

    0 讨论(0)
提交回复
热议问题