File size: 1,780 Bytes
5dbde27 2d57d00 e7b5496 5dbde27 2d57d00 182904b 2d57d00 f4454d4 2d57d00 5dbde27 2d57d00 b1e3e6e 2d57d00 a8c3caa 2d57d00 e7b5496 5dbde27 2d57d00 e7b5496 2d57d00 e7b5496 2d57d00 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 |
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
# Convert both to RGB and resize
top = top_img.convert("RGB")
bg = bg_img.convert("RGBA").resize(top.size)
top_np = np.array(top).astype(np.float32)
# Compute brightness from top image
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) # shape (H, W)
# Get alpha from background image
bg_np = np.array(bg).astype(np.float32) / 255.0
alpha_bg = bg_np[..., 3] # shape (H, W)
# Multiply alpha channels
combined_alpha = (alpha_top * alpha_bg).clip(0, 1)
# Create output RGBA: white RGB + combined alpha
height, width = combined_alpha.shape
white_rgb = np.ones((height, width, 3), dtype=np.float32) # all white
out_rgba = np.dstack((white_rgb, combined_alpha)) * 255
out_img = Image.fromarray(out_rgba.astype(np.uint8), mode="RGBA")
return out_img
# Gradio UI
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() |