Skip to main content

image-processing

Image processing and manipulation

Source facts

Repository
ffsshhttiikk/opencode-agents-skills
Last source activity
February 28, 2026 at 22:51
Detected SKILL.md language
English
Stars
3
Forks
2

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
image-processing
description
Image processing and manipulation
license
MIT
compatibility
opencode
metadata
{"audience":"developers","category":"utilities"}
## What I do - Resize and transform images - Handle image formats - Optimize image quality - Generate thumbnails - Extract image metadata - Apply filters and effects - Handle image uploads securely - Serve optimized images ## When to use me When implementing image processing or handling image uploads. ## Image Processing Basics ```python from PIL import Image, ImageFilter, ImageEnhance from dataclasses import dataclass from pathlib import Path from typing import Optional, List, Tuple import io @dataclass class ImageDimensions: """Image dimensions.""" width: int height: int @property def aspect_ratio(self) -> float: return self.width / self.height def resize(self, max_width: int, max_height: int) -> 'ImageDimensions': """Resize while maintaining aspect ratio.""" ratio = min(max_width / self.width, max_height / self.height) return ImageDimensions( width=int(self.width * ratio), height=int(self.height * ratio) ) @dataclass class ImageConfig: """Image processing configuration.""" format: str = "JPEG" quality: int = 85 optimize: bool = True preserve_metadata: bool = False class ImageProcessor: """Image processing operations.""" def __init__(self, config: ImageConfig = None): self.config = config or ImageConfig() def open(self, image_path: Path) -> Image: """Open an image file.""" return Image.open(image_path) def resize( self, image: Image, width: int, height: int, maintain_aspect: bool = True ) -> Image: """Resize image.""" if maintain_aspect: current_dims = ImageDimensions(image.width, image.height) new_dims = current_dims.resize(width, height) width, height = new_dims.width, new_dims.height return image.resize((width, height), Image.LANCZOS) def create_thumbnail( self, image: Image, max_size: Tuple[int, int] = (300, 300) ) -> Image: """Create thumbnail preserving aspect ratio.""" image.thumbnail(max_size, Image.LANCZOS) return image def crop( self, image: Image, left: int, top: int, right: int, bottom: int ) -> Image: """Crop image.""" return image.crop((left, top, right, bottom)) def rotate(self, image: Image, degrees: float) -> Image: """Rotate image.""" return image.rotate(-degrees, expand=True) def flip_horizontal(self, image: Image) -> Image: """Flip image horizontally.""" return image.transpose(Image.FLIP_LEFT_RIGHT) def flip_vertical(self, image: Image) -> Image: """Flip image vertically.""" return image.transpose(Image.FLIP_TOP_BOTTOM) class ImageFilterApplier: """Apply filters to images.""" @staticmethod def blur(image: Image, radius: float = 2) -> Image: """Apply Gaussian blur.""" return image.filter(ImageFilter.GaussianBlur(radius)) @staticmethod def sharpen(image: Image) -> Image: """Sharpen image.""" return image.filter(ImageFilter.SHARPEN) @staticmethod def contour(image: Image) -> Image: """Apply contour filter.""" return image.filter(ImageFilter.CONTOUR) @staticmethod def edge_enhance(image: Image) -> Image: """Edge enhancement.""" return image.filter(ImageFilter.EDGE_ENHANCE) @staticmethod def emboss(image: Image) -> Image: """Apply emboss effect.""" return image.filter(ImageFilter.EMBOSS) @staticmethod def adjust_brightness(image: Image, factor: float) -> Image: """Adjust brightness.""" enhancer = ImageEnhance.Brightness(image) return enhancer.enhance(factor) @staticmethod def adjust_contrast(image: Image, factor: float) -> Image: """Adjust contrast.""" enhancer = ImageEnhance.Contrast(image) return enhancer.enhance(factor) @staticmethod def adjust_saturation(image: Image, factor: float) -> Image: """Adjust saturation.""" enhancer = ImageEnhance.Color(image) return enhancer.enhance(factor) class ImageOptimizer: """Optimize images for web.""" def __init__(self, config: ImageConfig = None): self.config = config or ImageConfig() def optimize( self, image: Image, output_format: str = None ) -> Image: """Optimize image.""" format = output_format or self.config.format if format.upper() == "JPEG": image = image.convert("RGB") return image def save_with_quality( self, image: Image, output_path: Path, quality: int = None, format: str = None ) -> None: """Save image with specific quality.""" quality = quality or self.config.quality format = format or self.config.format save_kwargs = { "quality": quality, "optimize": self.config.optimize, } if format.upper() == "JPEG": save_kwargs["subsampling"] = 0 image.save(output_path, format=format, **save_kwargs) def save_to_bytes( self, image: Image, format: str = None, quality: int = None ) -> bytes: """Save image to bytes.""" format = format or self.config.format quality = quality or self.config.quality buffer = io.BytesIO() save_kwargs = { "quality": quality, "optimize": self.config.optimize, } image.save(buffer, format=format, **save_kwargs) return buffer.getvalue() def create_responsive_set( self, image: Image, sizes: List[Tuple[int, str]], output_dir: Path, prefix: str = "image" ) -> List[dict]: """Create responsive image set.""" results = [] for width, suffix in sizes: new_height = int(image.height * (width / image.width)) resized = self.resize( image, width, new_height, maintain_aspect=True ) filename = f"{prefix}_{suffix}.jpg" output_path = output_dir / filename self.save_with_quality(resized, output_path) results.append({ "filename": filename, "width": resized.width, "height": resized.height, "url": f"/images/{filename}" }) return results ``` ## Image Upload Handling ```python from pathlib import Path from typing import Optional import magic import hashlib class SecureImageUploader: """Secure image upload handling.""" ALLOWED_TYPES = { "image/jpeg": ".jpg", "image/png": ".png", "image/gif": ".gif", "image/webp": ".webp", } MAX_SIZE = 10 * 1024 * 1024 # 10MB def __init__(self, upload_dir: Path, processor: ImageProcessor): self.upload_dir = upload_dir self.processor = processor self.upload_dir.mkdir(parents=True, exist_ok=True) async def save_upload( self, file_content: bytes, original_filename: str ) -> dict: """Save uploaded image securely.""" # Validate file type mime_type = magic.from_buffer(file_content, mime=True) if mime_type not in self.ALLOWED_TYPES: raise InvalidImageError( f"Invalid file type: {mime_type}" ) # Validate size if len(file_content) > self.MAX_SIZE: raise InvalidImageError( f"File too large: {len(file_content)} bytes" ) # Generate safe filename ext = self.ALLOWED_TYPES[mime_type] safe_filename = self._generate_safe_filename(original_filename, ext) file_path = self.upload_dir / safe_filename # Save file file_path.write_bytes(file_content) # Process image image = self.processor.open(file_path) # Create thumbnail thumbnail = self.processor.create_thumbnail(image) thumbnail_path = self.upload_dir / f"thumb_{safe_filename}" self.processor.save_with_quality(thumbnail, thumbnail_path) return { "original": str(file_path), "thumbnail": str(thumbnail_path), "filename": safe_filename, "width": image.width, "height": image.height, "size": len(file_content), "type": mime_type, } def _generate_safe_filename( self, original_filename: str, extension: str ) -> str: """Generate safe, unique filename.""" # Get base name stem = Path(original_filename).stem # Sanitize safe_stem = "".join( c for c in stem if c.isalnum() or c in "-_" ) safe_stem = safe_stem[:50] # Limit length # Add hash for uniqueness hash_suffix = hashlib.md5( f"{original_filename}{datetime.utcnow().isoformat()}".encode() ).hexdigest()[:8] return f"{safe_stem}_{hash_suffix}{extension}" ``` ## Image Analysis ```python from PIL import ImageDraw, ImageFont from collections import Counter class ImageAnalyzer: """Analyze image properties.""" @staticmethod def get_dimensions(image: Image) -> Tuple[int, int]: """Get image dimensions.""" return image.width, image.height @staticmethod def get_format(image: Image) -> str: """Get image format.""" return image.format or "Unknown" @staticmethod def get_mode(image: Image) -> str: """Get image mode (RGB, L, etc.).""" return image.mode @staticmethod def get_info(image: Image) -> dict: """Get comprehensive image info.""" return { "format": image.format, "mode": image.mode, "width": image.width, "height": image.height, "size_bytes": image.size[0] * image.size[1], "has_alpha": image.mode in ("RGBA", "LA", "P"), "aspect_ratio": image.width / image.height if image.height else 0, } @staticmethod def get_color_histogram(image: Image) -> dict: """Get color histogram.""" if image.mode != "RGB": image = image.convert("RGB") colors = list(image.getdata()) color_counts = Counter(colors) return { "unique_colors": len(color_counts), "top_colors": color_counts.most_common(10), } @staticmethod def is_portrait(image: Image) -> bool: """Check if image is portrait orientation.""" return image.height > image.width @staticmethod def is_landscape(image: Image) -> bool: """Check if image is landscape orientation.""" return image.width > image.height @staticmethod def is_square(image: Image) -> bool: """Check if image is square.""" return image.width == image.height @staticmethod def estimate_quality(image: Image) -> str: """Estimate image quality level.""" width = image.width height = image.height if width < 300 or height < 300: return "low" elif width < 800 or height < 800: return "medium" elif width < 2000 or height < 2000: return "high" else: return "very_high" # Watermark application class WatermarkApplier: """Apply watermarks to images.""" def __init__(self, text: str, font_size: int = 24): self.text = text self.font_size = font_size def add_text_watermark( self, image: Image, position: str = "bottom-right", opacity: float = 0.5 ) -> Image: """Add text watermark.""" if image.mode != "RGBA": image = image.convert("RGBA") watermark = Image.new("RGBA", image.size, (255, 255, 255, 0)) draw = ImageDraw.Draw(watermark) # Calculate position width, height = image.size if position == "bottom-right": x = width - 200 y = height - 50 elif position == "bottom-left": x = 20 y = height - 50
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub