TIMBOVILL commited on
Commit
6bdc2eb
·
verified ·
1 Parent(s): 188e92b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -31
app.py CHANGED
@@ -6,56 +6,55 @@ def brightness_to_opacity_overlay(foreground_img, background_img, invert_opacity
6
  if foreground_img is None or background_img is None:
7
  return None
8
 
9
- # Resize foreground to match background
10
  bg = background_img.convert("RGBA")
11
  fg = foreground_img.convert("RGB").resize(bg.size)
12
 
13
- # Convert to luminance (grayscale)
14
- fg_array = np.array(fg)
15
- luminance = np.dot(fg_array[...,:3], [0.299, 0.587, 0.114]).astype(np.uint8)
16
 
17
- # Invert if requested
18
- alpha = 255 - luminance if invert_opacity else luminance
19
 
20
- # Create white RGBA image with computed alpha
21
- white_rgb = np.ones_like(fg_array) * 255
22
- rgba_array = np.dstack((white_rgb, alpha)).astype(np.uint8)
23
- overlay = Image.fromarray(rgba_array, mode="RGBA")
24
 
25
- # Manual alpha blending
26
- bg_arr = np.array(bg).astype(np.float32) / 255.0
27
- ov_arr = np.array(overlay).astype(np.float32) / 255.0
28
 
29
- # Extract alpha channels
30
- alpha_bg = bg_arr[..., 3:4]
31
- alpha_ov = ov_arr[..., 3:4]
32
 
33
- # Composite alpha and color
34
- out_alpha = alpha_ov + alpha_bg * (1 - alpha_ov)
35
- out_rgb = (
36
- ov_arr[..., :3] * alpha_ov +
37
- bg_arr[..., :3] * alpha_bg * (1 - alpha_ov)
38
- ) / np.clip(out_alpha, 1e-6, 1)
39
 
40
- # Combine and convert to final image
41
- out_image = np.dstack((out_rgb, out_alpha)).clip(0, 1) * 255
42
- out_image = Image.fromarray(out_image.astype(np.uint8), mode="RGBA")
43
 
44
- return out_image
 
 
 
 
45
 
46
  # Gradio UI
47
  iface = gr.Interface(
48
  fn=brightness_to_opacity_overlay,
49
  inputs=[
50
  gr.Image(type="pil", label="Mask Source (Brightness to Alpha)"),
51
- gr.Image(type="pil", label="Background Image (with or without transparency)"),
52
  gr.Checkbox(label="Invert Opacity", value=False)
53
  ],
54
- outputs=gr.Image(type="pil", label="Final Composite"),
55
- title="Brightness-to-Alpha Overlay Tool (with Transparency Fix)",
56
  description=(
57
- "Uses the brightness of the first image as alpha, resizes to match the second image, "
58
- "and overlays correctly even when the background has transparency."
59
  )
60
  )
61
 
 
6
  if foreground_img is None or background_img is None:
7
  return None
8
 
9
+ # Ensure images are RGBA and same size
10
  bg = background_img.convert("RGBA")
11
  fg = foreground_img.convert("RGB").resize(bg.size)
12
 
13
+ # Convert to luminance (brightness)
14
+ fg_np = np.array(fg)
15
+ brightness = np.dot(fg_np[..., :3], [0.299, 0.587, 0.114]).astype(np.uint8)
16
 
17
+ # Optionally invert
18
+ alpha = 255 - brightness if invert_opacity else brightness
19
 
20
+ # Create white RGBA with computed alpha
21
+ white_rgb = np.full_like(fg_np, 255)
22
+ overlay_rgba = np.dstack((white_rgb, alpha)).astype(np.uint8)
23
+ overlay = Image.fromarray(overlay_rgba, mode="RGBA")
24
 
25
+ # Use the alpha from overlay as a mask on the background
26
+ bg_np = np.array(bg).astype(np.float32)
27
+ ov_np = np.array(overlay).astype(np.float32)
28
 
29
+ alpha_fg = ov_np[..., 3:4] / 255.0
30
+ alpha_bg = bg_np[..., 3:4] / 255.0
 
31
 
32
+ # Blend RGB
33
+ out_rgb = (ov_np[..., :3] * alpha_fg + bg_np[..., :3] * alpha_bg * (1 - alpha_fg))
34
+ out_alpha = alpha_fg + alpha_bg * (1 - alpha_fg)
 
 
 
35
 
36
+ # Avoid divide-by-zero
37
+ out_rgb = np.divide(out_rgb, out_alpha, where=(out_alpha != 0))
 
38
 
39
+ # Combine back to RGBA
40
+ out_rgba = np.dstack((out_rgb, out_alpha)) * 255
41
+ result = Image.fromarray(out_rgba.astype(np.uint8), mode="RGBA")
42
+
43
+ return result
44
 
45
  # Gradio UI
46
  iface = gr.Interface(
47
  fn=brightness_to_opacity_overlay,
48
  inputs=[
49
  gr.Image(type="pil", label="Mask Source (Brightness to Alpha)"),
50
+ gr.Image(type="pil", label="Background Image (with transparency OK)"),
51
  gr.Checkbox(label="Invert Opacity", value=False)
52
  ],
53
+ outputs=gr.Image(type="pil", label="Composite Result"),
54
+ title="Brightness-to-Alpha Overlay (Transparent-Safe)",
55
  description=(
56
+ "Uses the brightness of one image as an alpha mask and overlays it "
57
+ "on a background image — works properly even when background has transparency."
58
  )
59
  )
60