How to fade an image with transparency from the top using Python (Pillow)

Viewed 51

I'm having trouble figuring out how to fade an image that has transparency from the top, I know something like this works, however, manipulating it to fade from the top instead of the bottom is proving quite difficult. I was wondering if I could get some help.

Current code for fading images (towards the bottom, not top, I need top and bottom) looks like:

def image_fade(im: Image, fade_start, fade_finish, from_top: bool = False):
    width, height = im.size
    pixels = im.load()
    
    fade_range = list(range(int(height*fade_start), int(height*fade_finish)))
    
    if from_top:
        for y in fade_range:
            for x in range(width):
                alpha = int((y - height*fade_start)/height/(fade_finish - fade_start) * 255)
                alpha = 0 if alpha <= 0 else alpha
                pixels[x, y] = pixels[x, y][:3] + (alpha,)

        for y in range(height, y):
            for x in range(width):
                pixels[x, y] = pixels[x, y][:3] + (0,)

    else:
        for y in fade_range:
            for x in range(width):
                alpha = pixels[x, y][3]-int((y - height*fade_start)/height/(fade_finish - fade_start) * 255)
                alpha = 0 if alpha <= 0 else alpha
                pixels[x, y] = pixels[x, y][:3] + (alpha,)

        for y in range(y, height):
            for x in range(width):
                pixels[x, y] = pixels[x, y][:3] + (0,)
            
    return im

Fade start and finish should be equal on both sides, meaning if we pass the parameters 0.7, 0.9 for fade_start and fade_finish, the top half should be (1-fade_finish), (1-fade_start), or (0.1, 0.3)

From something like:

enter image description here

I am trying to get something like (where the background is transparent, not white, say I want 10% of the top and bottom faded):

enter image description here

1 Answers

There are lots of ways of doing this. Here is one method. Basically, in order to make an image transparent, you need to create a greyscale alpha/transparency image which is black where you want the image to be transparent and white where you want it to be opaque. Then push that into your image as an alpha layer and save to a format that supports transparency (PNG, TIFF) as opposed to JPEG.

So, starting with this image:

enter image description here

#!/usr/bin/env python3

from PIL import Image

# Load image and get dimensions
im = Image.open('RandomColouredSquares.png')
w, h = im.size

# Make a linear gradient and resize to match width of input image and 10% of its height
gradient = Image.linear_gradient('L')
gradient = gradient.resize((w,int(h/10)))

gradient looks like this:

enter image description here

# Make a new, fully opaque transparency layer (i.e. white) to match input image size
alpha = Image.new('L', (w,h), 'white')

# Paste the gradient into the top-left, then flip top to bottom and paste again
alpha.paste(gradient)
alpha = alpha.transpose(Image.Transpose.FLIP_TOP_BOTTOM)
alpha.paste(gradient)

alpha looks like this:

enter image description here

# Now push that alpha layer into the original and save
im.putalpha(alpha)
im.save('result.png')

enter image description here

Related