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")