Skip to content Skip to sidebar Skip to footer

Fill An Image With Color But Keep The Alpha (color Overlay In Pil)

Basically, I'm trying to make a function that will take a given image and a color. for each pixel in the image, it will keep the original alpha value but will change the color to t

Solution 1:

One way of doing it is to create a solid red image the same size as the original and then copy the alpha channel from the original image across to it:

from PIL import Image

# Open original image and extract the alpha channel
im = Image.open('arrow.png')
alpha = im.getchannel('A')

# Create red image the same size and copy alpha channel across
red = Image.new('RGBA', im.size, color='red')
red.putalpha(alpha) 

enter image description here


Here is a second method using Numpy:

from PIL import Image
import numpy as np

# Open image
im = Image.open('arrow.png')

# Make into Numpy array
n = np.array(im) 

# Set first three channels to red
n[...,0:3]=[255,0,0] 

# Convert back to PIL Image and save
Image.fromarray(n).save('result.png')

A third way is to composite with a similarly-sized red copy and use the original alpha mask:

from PIL import Image

# Open image
im = Image.open('arrow.png')                                                                                                       

# Make solid red image same size
red = Image.new('RGBA', im.size, color='red')                                                                                      

# Composite the two together, honouring the original mask
im = Image.composite(red,im,im)  

Keywords: Image, image processing, Python, Pillow, PIL, Numpy, extract alpha, alpha channel, transparency, replace transparency, copy transparency, copy alpha, transplant alpha, transplant transparency.

Solution 2:

Let us consider the following image - http://www.libpng.org/pub/png/img_png/globe-scene-fish-bowl-pngcrush.png

image = cv2.imread("/home/thalish/bleed_test/globe-scene-fish-bowl-pngcrush.png",cv2.IMREAD_UNCHANGED)

image[:,:,0],image[:,:,1],image[:,:,2] = (255,0,0) #to replace all pixels with Red but keep alpha channel unchanged

Final Image

Solution 3:

Try:

from PIL import Image

# Takes the input image
img = Image.open(r"Arrow.png")

# Getting the dimensions of the image
x, y = img.size

# Obtaining values of Red, Green, Blue for each opaque pixel
red = int(input("Enter the red value you want in each pixel = "))
green = int(input("Enter the green value you want in each pixel = "))
blue = int(input("Enter the blue value you want in each pixel = "))

i = j = 0# This loop makes sure that alpha only has two discrete values (0 , 255)# This is to ensure that constant color is obtained, at pixels where transparence may not be 255# (prevents color escapes at pixels where total transparency is not achieved)while i < x:
    while j < y:
        r, g, b, a = img.getpixel((i,j))
        if a > 200and a < 256:
            a = 255else:
            a = 0
        img.putpixel((i,j),(r,g,b,a))
        j += 1
    j = 0
    i += 1

i = j = 0# Two nested loops# Outer one goes through rows of image# Inner one (nested one) goes through columns of imagewhile i < x:
    while j < y:

        # This condition checks, if the value of alpha for that individual pixel is 255 (~opaque), # if true then change its RGB values to user defined valuesif img.getpixel((i,j))[-1] == 255:
            img.putpixel((i,j), (red, green, blue, 255))
        j += 1
    j = 0
    i += 1

img.save("Arrow.png")

INPUT:-

Enter the red value you want in eachpixel=0
Enter the green value you want in eachpixel=0
Enter the blue value you want in eachpixel=255

OUTPUT:-

EXPLANATION FOR THE FIRST LOOP:-

If the first loop doesn't flat out, the alpha values by a threshold, then a lot of error gets produced in the output image. i.e. Pixel values near the edge of a object tends to have alpha pixel values a little lesser than 255 (total opacity) to enable smooth anti-aliasing. If these pixels are discarded then output image may look something like this:-

Notice the unwanted color's in the edge of the arrow

P.S.:- Even though OpenCV would be the preferred choice for most Image Analysts/Experts, I would definitely advice you to stick with PIL/Pillow at the beginning, as it allows you to get the grasp the fundamentals of imaging in a really friendly way. There is no denying that OpenCV far outweighs PIL in almost every aspect, but still if you learn PIL in the beginning, transitioning from PIL to OpenCV would be alot easier for you to do later on.

Post a Comment for "Fill An Image With Color But Keep The Alpha (color Overlay In Pil)"