pngwn's picture
pngwn HF staff
Update app.py
d3530a8 verified
import gradio as gr
from PIL import Image
import numpy as np
from typing import TypedDict
def combine_masks(im_1: np.ndarray, im_2: np.ndarray):
"""
Layers images on top of each other, with the foreground image overwriting the background.
params:
im_1: background image
im_2: foreground image
return:
combined image
"""
if im_1.shape != im_2.shape:
raise ValueError("Images must have the same dimensions")
# replace rgb values of the background with the foreground where foreground is not fully transparent
foreground_mask = im_2[:, :, 3] > 0
im_1[foreground_mask] = im_2[foreground_mask]
return im_1
def make_grey(image: np.ndarray, grey_value: int = 128):
"""
Converts opaque pixels within an image to a static grey value.
params:
image: RGBA image
return:
greyscale image
"""
rgb = image[:, :, :3]
alpha = image[:, :, 3]
opaque_mask = alpha == 255
# arbitrary grey value
# apply grey values to the opaque pixels
rgb[opaque_mask] = np.stack((grey_value, grey_value, grey_value), axis=-1)
# combine channels and return
return np.dstack((rgb, alpha))
class ImageData(TypedDict):
background: np.ndarray
layers: list[np.ndarray]
def mask(image: ImageData):
bg = image.get("background", None)
layers = image.get("layers", [])
if bg is None and not layers:
raise ValueError("No background or layers provided")
mask = layers[0]
for layer in layers[1:]:
mask = combine_masks(mask, layer)
# save images or use them elsewhere
# Image.fromarray(mask).save("mask.png")
# Image.fromarray(bg).save("bg.png")
mask = make_grey(mask)
return [bg, mask]
with gr.Blocks() as demo:
imed = gr.ImageEditor()
im_1 = gr.Image()
im_2 = gr.Image()
imed.apply(mask, inputs=imed, outputs=[im_1, im_2])
if __name__ == "__main__":
demo.launch()