|
import gradio as gr |
|
from PIL import Image |
|
import numpy as np |
|
|
|
def white_alpha_overlay(mask_img, bg_img, invert_opacity=False): |
|
if mask_img is None or bg_img is None: |
|
return None |
|
|
|
|
|
mask = mask_img.convert("RGB") |
|
bg = bg_img.convert("RGBA") |
|
mask = mask.resize(bg.size) |
|
|
|
|
|
mask_np = np.array(mask).astype(np.float32) |
|
brightness = np.dot(mask_np[..., :3], [0.299, 0.587, 0.114]) |
|
if invert_opacity: |
|
brightness = 255 - brightness |
|
alpha = brightness.clip(0, 255) / 255.0 |
|
|
|
|
|
white = np.ones_like(mask_np) / 255.0 |
|
white_rgba = np.dstack((white, alpha)) |
|
|
|
|
|
bg_np = np.array(bg).astype(np.float32) / 255.0 |
|
|
|
|
|
alpha_fg = white_rgba[..., 3:4] |
|
alpha_bg = bg_np[..., 3:4] |
|
out_alpha = alpha_fg + alpha_bg * (1 - alpha_fg) |
|
out_rgb = (white_rgba[..., :3] * alpha_fg + bg_np[..., :3] * alpha_bg * (1 - alpha_fg)) / np.maximum(out_alpha, 1e-6) |
|
|
|
|
|
out_img = np.dstack((out_rgb, out_alpha)).clip(0, 1) * 255 |
|
result = Image.fromarray(out_img.astype(np.uint8), mode="RGBA") |
|
return result |
|
|
|
|
|
iface = gr.Interface( |
|
fn=white_alpha_overlay, |
|
inputs=[ |
|
gr.Image(type="pil", label="Mask Image (Used for Brightness β Alpha)"), |
|
gr.Image(type="pil", label="Background Image (With Alpha OK)"), |
|
gr.Checkbox(label="Invert Brightness to Alpha", value=False) |
|
], |
|
outputs=gr.Image(type="pil", label="White Overlay Composite"), |
|
title="ποΈ Brightness-to-Alpha White Overlay", |
|
description=( |
|
"Converts the brightness of the top image into opacity, sets the image color to white, " |
|
"and overlays it on a background. Works with full transparency." |
|
) |
|
) |
|
|
|
if __name__ == "__main__": |
|
iface.launch() |