# /// script # requires-python = ">=3.10" # dependencies = ["numpy", "opencv-python"] # /// """ @effect pixelate @version 1.0.0 @author artdag @description Pixelate effect. Reduces resolution to create blocky, retro pixel art look. Great for 8-bit aesthetics. @param block_size int @range 2 64 @default 8 Size of pixel blocks. Larger = more pixelated. @param maintain_edges bool @default false Try to preserve edges while pixelating. @example (effect pixelate :block_size 16) @example ;; Beat-reactive pixelation (effect pixelate :block_size (bind bass :range [4 32])) """ import numpy as np import cv2 def process_frame(frame: np.ndarray, params: dict, state: dict) -> tuple: """ Apply pixelate effect to a video frame. Args: frame: Input frame as numpy array (H, W, 3) RGB uint8 params: Effect parameters - block_size: pixel block size (default 8) - maintain_edges: preserve edges (default False) state: Persistent state dict Returns: Tuple of (processed_frame, new_state) """ block_size = max(2, min(int(params.get("block_size", 8)), 64)) maintain_edges = params.get("maintain_edges", False) if state is None: state = {} h, w = frame.shape[:2] # Scale down then up to create pixelation small_h = max(1, h // block_size) small_w = max(1, w // block_size) small = cv2.resize(frame, (small_w, small_h), interpolation=cv2.INTER_AREA) result = cv2.resize(small, (w, h), interpolation=cv2.INTER_NEAREST) if maintain_edges: # Detect edges in original and overlay gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) edges = cv2.Canny(gray, 50, 150) edges_dilated = cv2.dilate(edges, np.ones((2, 2), np.uint8)) edge_mask = edges_dilated > 0 result[edge_mask] = frame[edge_mask] return result, state