Spaces:
Sleeping
Sleeping
| from PIL import Image, ImageEnhance | |
| from rembg import remove | |
| from logger import get_logger | |
| logger = get_logger("image_utils") | |
| def load_and_process_image( | |
| uploaded_file, | |
| session, | |
| transparency_mode, | |
| rgb_color, | |
| add_watermark=False, | |
| watermark_file=None, | |
| wm_opacity=0.15, | |
| wm_scale=0.33, | |
| wm_position="bottom-right", | |
| ): | |
| logger.info(f"Opening image: {uploaded_file.name}") | |
| input_image = Image.open(uploaded_file) | |
| # Remove background | |
| output = remove(input_image, session=session) | |
| watermark_img = Image.open(watermark_file) if watermark_file else None | |
| # Handle transparency | |
| if transparency_mode == "Keep transparent": | |
| processed = output | |
| else: | |
| background = Image.new("RGB", output.size, rgb_color) | |
| background.paste(output, (0, 0), output) | |
| processed = background | |
| # Apply watermark if enabled | |
| if add_watermark and watermark_img is not None: | |
| processed = apply_watermark( | |
| processed, watermark_img, opacity=wm_opacity, scale=wm_scale, position=wm_position | |
| ) | |
| return input_image, processed | |
| def apply_watermark0(base_img, watermark_img, opacity=0.15, scale=0.33, position="bottom-right"): | |
| # Ensure watermark has alpha | |
| watermark = watermark_img.convert("RGBA") | |
| # Resize watermark relative to base image width | |
| base_w, base_h = base_img.size | |
| new_w = int(base_w * scale) | |
| aspect_ratio = watermark.height / watermark.width | |
| new_h = int(new_w * aspect_ratio) | |
| watermark = watermark.resize((new_w, new_h), Image.LANCZOS) | |
| # Apply opacity | |
| alpha = watermark.split()[3] | |
| alpha = ImageEnhance.Brightness(alpha).enhance(opacity) | |
| watermark.putalpha(alpha) | |
| # Determine position | |
| if position == "bottom-right": | |
| pos = (base_w - new_w - 10, base_h - new_h - 10) | |
| elif position == "bottom-left": | |
| pos = (10, base_h - new_h - 10) | |
| elif position == "top-right": | |
| pos = (base_w - new_w - 10, 10) | |
| else: # top-left | |
| pos = (10, 10) | |
| # Composite watermark | |
| base_img = base_img.convert("RGBA") | |
| base_img.paste(watermark, pos, watermark) | |
| return base_img | |
| def apply_watermark( | |
| base_img, | |
| watermark_img, | |
| opacity=0.15, | |
| scale=0.33, | |
| position="bottom-right", | |
| margin=10, | |
| ): | |
| """ | |
| Apply watermark with pure transparency - no color changes. | |
| Args: | |
| opacity: 0.0 (fully transparent) to 1.0 (fully opaque) | |
| """ | |
| base = base_img.convert("RGBA") | |
| wm = watermark_img.convert("RGBA") | |
| # Resize watermark relative to base width | |
| base_w, base_h = base.size | |
| new_w = int(base_w * scale) | |
| aspect = wm.height / wm.width | |
| new_h = int(new_w * aspect) | |
| wm = wm.resize((new_w, new_h), Image.LANCZOS) | |
| # Apply transparency to alpha channel ONLY - colors remain untouched | |
| r, g, b, a = wm.split() | |
| # Multiply alpha by opacity (keeps RGB exactly the same) | |
| a = a.point(lambda p: int(p * opacity)) | |
| wm = Image.merge("RGBA", (r, g, b, a)) | |
| # Position | |
| if position == "bottom-right": | |
| pos = (base_w - new_w - margin, base_h - new_h - margin) | |
| elif position == "bottom-left": | |
| pos = (margin, base_h - new_h - margin) | |
| elif position == "top-right": | |
| pos = (base_w - new_w - margin, margin) | |
| else: # top-left | |
| pos = (margin, margin) | |
| # Composite using alpha_composite for proper blending | |
| layer = Image.new("RGBA", base.size, (0, 0, 0, 0)) | |
| layer.paste(wm, pos) | |
| return Image.alpha_composite(base, layer) | |
| def apply_watermark2(base_img, watermark_img, opacity=0.15, scale=0.33, position="bottom-right"): | |
| # Ensure base image is RGBA | |
| base = base_img.convert("RGBA") | |
| # Ensure watermark is RGBA | |
| wm = watermark_img.convert("RGBA") | |
| # Resize watermark relative to base width | |
| base_w, base_h = base.size | |
| new_w = int(base_w * scale) | |
| aspect = wm.height / wm.width | |
| new_h = int(new_w * aspect) | |
| wm = wm.resize((new_w, new_h), Image.LANCZOS) | |
| # Apply opacity WITHOUT altering colors | |
| # Extract alpha channel | |
| alpha = wm.split()[3] | |
| # Adjust brightness of alpha only | |
| alpha = ImageEnhance.Brightness(alpha).enhance(1 - opacity) | |
| wm.putalpha(alpha) | |
| # Determine position | |
| if position == "bottom-right": | |
| pos = (base_w - new_w - 10, base_h - new_h - 10) | |
| elif position == "bottom-left": | |
| pos = (10, base_h - new_h - 10) | |
| elif position == "top-right": | |
| pos = (base_w - new_w - 10, 10) | |
| else: # top-left | |
| pos = (10, 10) | |
| # Composite watermark onto base | |
| combined = Image.new("RGBA", base.size) | |
| combined.paste(base, (0, 0)) | |
| combined.paste(wm, pos, wm) | |
| return combined.convert("RGBA") | |