File size: 2,165 Bytes
5dbde27 e7b5496 5dbde27 e7b5496 5dbde27 188e92b e7b5496 5dbde27 188e92b e7b5496 5dbde27 188e92b e7b5496 188e92b 5dbde27 188e92b e7b5496 188e92b e7b5496 5dbde27 e7b5496 188e92b e7b5496 188e92b e7b5496 188e92b e7b5496 5dbde27 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
import gradio as gr
from PIL import Image
import numpy as np
def brightness_to_opacity_overlay(foreground_img, background_img, invert_opacity=False):
if foreground_img is None or background_img is None:
return None
# Resize foreground to match background
bg = background_img.convert("RGBA")
fg = foreground_img.convert("RGB").resize(bg.size)
# Convert to luminance (grayscale)
fg_array = np.array(fg)
luminance = np.dot(fg_array[...,:3], [0.299, 0.587, 0.114]).astype(np.uint8)
# Invert if requested
alpha = 255 - luminance if invert_opacity else luminance
# Create white RGBA image with computed alpha
white_rgb = np.ones_like(fg_array) * 255
rgba_array = np.dstack((white_rgb, alpha)).astype(np.uint8)
overlay = Image.fromarray(rgba_array, mode="RGBA")
# Manual alpha blending
bg_arr = np.array(bg).astype(np.float32) / 255.0
ov_arr = np.array(overlay).astype(np.float32) / 255.0
# Extract alpha channels
alpha_bg = bg_arr[..., 3:4]
alpha_ov = ov_arr[..., 3:4]
# Composite alpha and color
out_alpha = alpha_ov + alpha_bg * (1 - alpha_ov)
out_rgb = (
ov_arr[..., :3] * alpha_ov +
bg_arr[..., :3] * alpha_bg * (1 - alpha_ov)
) / np.clip(out_alpha, 1e-6, 1)
# Combine and convert to final image
out_image = np.dstack((out_rgb, out_alpha)).clip(0, 1) * 255
out_image = Image.fromarray(out_image.astype(np.uint8), mode="RGBA")
return out_image
# Gradio UI
iface = gr.Interface(
fn=brightness_to_opacity_overlay,
inputs=[
gr.Image(type="pil", label="Mask Source (Brightness to Alpha)"),
gr.Image(type="pil", label="Background Image (with or without transparency)"),
gr.Checkbox(label="Invert Opacity", value=False)
],
outputs=gr.Image(type="pil", label="Final Composite"),
title="Brightness-to-Alpha Overlay Tool (with Transparency Fix)",
description=(
"Uses the brightness of the first image as alpha, resizes to match the second image, "
"and overlays correctly even when the background has transparency."
)
)
if __name__ == "__main__":
iface.launch() |