import numpy as np from PIL import Image, ImageOps import io import base64 def resize_image(image, max_size=1024): """ Resize image to maximum dimension while maintaining aspect ratio. Args: image (PIL.Image): Input image max_size (int): Maximum dimension size Returns: PIL.Image: Resized image """ if image is None: return None # Get current dimensions width, height = image.size # Calculate new dimensions if max(width, height) > max_size: if width > height: new_width = max_size new_height = int(height * max_size / width) else: new_height = max_size new_width = int(width * max_size / height) image = image.resize((new_width, new_height), Image.Resampling.LANCZOS) return image def convert_to_rgba(image): """ Convert image to RGBA format with transparency. Args: image (PIL.Image): Input image Returns: PIL.Image: RGBA image """ if image is None: return None if image.mode != 'RGBA': image = image.convert('RGBA') return image def image_to_base64(image): """ Convert PIL image to base64 string. Args: image (PIL.Image): Input image Returns: str: Base64 encoded image """ if image is None: return None buffer = io.BytesIO() image.save(buffer, format='PNG') buffer.seek(0) return base64.b64encode(buffer.getvalue()).decode('utf-8') def base64_to_image(base64_string): """ Convert base64 string to PIL image. Args: base64_string (str): Base64 encoded image Returns: PIL.Image: Decoded image """ if base64_string is None: return None try: image_bytes = base64.b64decode(base64_string) return Image.open(io.BytesIO(image_bytes)) except Exception as e: raise ValueError(f"Invalid base64 image data: {str(e)}") def validate_image(image): """ Validate that the input is a proper image. Args: image: Input to validate Returns: bool: True if valid image """ if image is None: return False try: if isinstance(image, np.ndarray): image = Image.fromarray(image) if hasattr(image, 'save'): # Test if image can be saved buffer = io.BytesIO() image.save(buffer, format='PNG') return True return False except Exception: return False def create_transparent_background(image, color=(255, 255, 255)): """ Replace transparent areas with specified color. Args: image (PIL.Image): Input image color (tuple): RGB color to use as background Returns: PIL.Image: Image with colored background """ if image is None: return None # Ensure image is RGBA if image.mode != 'RGBA': image = image.convert('RGBA') # Create background background = Image.new('RGB', image.size, color) background.paste(image, mask=image.split()[-1]) # Use alpha channel as mask return background def optimize_for_web(image, quality=85): """ Optimize image for web use. Args: image (PIL.Image): Input image quality (int): JPEG quality (1-100) Returns: PIL.Image: Optimized image """ if image is None: return None # Convert to RGB if no transparency if image.mode in ('RGBA', 'LA') and 'transparency' not in image.info: background = Image.new('RGB', image.size, (255, 255, 255)) background.paste(image, mask=image.split()[-1] if image.mode == 'RGBA' else None) image = background return image