4 changed files with 62 additions and 24 deletions
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 36 KiB |
@ -0,0 +1,62 @@ |
|||||||
|
from PIL import ImageOps, Image, ImageFilter |
||||||
|
|
||||||
|
FG_IMG_PATH = "fg.png" |
||||||
|
|
||||||
|
BG_IMG_PATH = "bg.jpeg" |
||||||
|
|
||||||
|
def load_image(path): |
||||||
|
|
||||||
|
"""Load an image using PIL.""" |
||||||
|
|
||||||
|
return Image.open(path) |
||||||
|
|
||||||
|
def extract_alpha(image): |
||||||
|
|
||||||
|
"""Extract the alpha channel from an image.""" |
||||||
|
|
||||||
|
return image.split()[-1] |
||||||
|
|
||||||
|
def create_shadow_from_alpha(alpha, blur_radius): |
||||||
|
|
||||||
|
"""Create a shadow based on a blurred version of the alpha channel.""" |
||||||
|
|
||||||
|
alpha_blur = alpha.filter(ImageFilter.BoxBlur(blur_radius)) |
||||||
|
|
||||||
|
shadow = Image.new(mode="RGB", size=alpha_blur.size) |
||||||
|
|
||||||
|
shadow.putalpha(alpha_blur) |
||||||
|
|
||||||
|
return shadow |
||||||
|
|
||||||
|
def composite_images(fg, shadow): |
||||||
|
|
||||||
|
"""Composite the shadow and foreground onto the background.""" |
||||||
|
|
||||||
|
shadow.paste(fg, (-5, 4), fg) |
||||||
|
|
||||||
|
return shadow |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
|
||||||
|
|
||||||
|
# Load the images |
||||||
|
|
||||||
|
fg = load_image(FG_IMG_PATH) |
||||||
|
|
||||||
|
# Create the shadow based on the alpha channel of the foreground |
||||||
|
|
||||||
|
alpha = extract_alpha(fg) |
||||||
|
|
||||||
|
shadow = create_shadow_from_alpha(alpha, blur_radius=1) |
||||||
|
|
||||||
|
# Composite the shadow and foreground onto the background |
||||||
|
|
||||||
|
final_image = composite_images(fg, shadow) |
||||||
|
|
||||||
|
# Display the final image (optional) |
||||||
|
|
||||||
|
final_image.show() |
||||||
|
|
||||||
|
# Save the final image |
||||||
|
|
||||||
|
final_image.save(f"final_image.png") |
||||||
Loading…
Reference in new issue