|
import gradio as gr |
|
from PIL import Image |
|
import numpy as np |
|
|
|
def combine_opacity_layers(top_img, bg_img, invert_opacity=False): |
|
if top_img is None or bg_img is None: |
|
return None |
|
|
|
|
|
top = top_img.convert("RGB") |
|
bg = bg_img.convert("RGBA").resize(top.size) |
|
top_np = np.array(top).astype(np.float32) |
|
|
|
|
|
brightness = np.dot(top_np[..., :3], [0.299, 0.587, 0.114]) |
|
if invert_opacity: |
|
brightness = 255 - brightness |
|
alpha_top = (brightness / 255.0).clip(0, 1) |
|
|
|
|
|
bg_np = np.array(bg).astype(np.float32) / 255.0 |
|
alpha_bg = bg_np[..., 3] |
|
|
|
|
|
combined_alpha = (alpha_top * alpha_bg).clip(0, 1) |
|
|
|
|
|
height, width = combined_alpha.shape |
|
white_rgb = np.ones((height, width, 3), dtype=np.float32) |
|
out_rgba = np.dstack((white_rgb, combined_alpha)) * 255 |
|
out_img = Image.fromarray(out_rgba.astype(np.uint8), mode="RGBA") |
|
return out_img |
|
|
|
|
|
iface = gr.Interface( |
|
fn=combine_opacity_layers, |
|
inputs=[ |
|
gr.Image(type="pil", label="Top Brightness-Based Image"), |
|
gr.Image(type="pil", label="Base Opacity Image (with alpha)"), |
|
gr.Checkbox(label="Invert Top Brightness", value=False) |
|
], |
|
outputs=gr.Image(type="pil", label="Combined Opacity Image"), |
|
title="π Combine Two Opacity Images (Multiply Alphas)", |
|
description=( |
|
"Takes two images and multiplies their opacity (alpha). Output is solid white " |
|
"with combined alpha values. Useful for stacking brightness masks." |
|
) |
|
) |
|
|
|
if __name__ == "__main__": |
|
iface.launch() |