mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
Replace the confusing 2-mode smart crop with a clear 3-mode system: - Subject Focus: Sharp attention/entropy saliency crop with social media presets - Face Focus: MediaPipe face detection with headshot framing presets - Auto Trim: Border removal with optional pad-to-square Adds detectFaces() to AI package, face preset constants, backward compatibility for old mode names, and comprehensive integration tests.
383 lines
10 KiB
TypeScript
383 lines
10 KiB
TypeScript
import type { CategoryInfo, SocialMediaPreset, Tool } from "./types.js";
|
|
|
|
export const CATEGORIES: CategoryInfo[] = [
|
|
{ id: "essentials", name: "Essentials", icon: "Layers", color: "#3B82F6" },
|
|
{ id: "optimization", name: "Optimization", icon: "Zap", color: "#10B981" },
|
|
{ id: "adjustments", name: "Adjustments", icon: "SlidersHorizontal", color: "#8B5CF6" },
|
|
{ id: "ai", name: "AI Tools", icon: "Sparkles", color: "#F59E0B" },
|
|
{ id: "watermark", name: "Watermark & Overlay", icon: "Stamp", color: "#EF4444" },
|
|
{ id: "utilities", name: "Utilities", icon: "Wrench", color: "#6366F1" },
|
|
{ id: "layout", name: "Layout & Composition", icon: "LayoutGrid", color: "#EC4899" },
|
|
{ id: "format", name: "Format & Conversion", icon: "FileType", color: "#14B8A6" },
|
|
{ id: "automation", name: "Automation", icon: "Workflow", color: "#F97316" },
|
|
];
|
|
|
|
export const TOOLS: Tool[] = [
|
|
// Essentials
|
|
{
|
|
id: "resize",
|
|
name: "Resize",
|
|
description: "Resize by pixels, percentage, or social media presets",
|
|
category: "essentials",
|
|
icon: "Maximize2",
|
|
route: "/resize",
|
|
},
|
|
{
|
|
id: "crop",
|
|
name: "Crop",
|
|
description: "Freeform crop, aspect ratio presets, shape crop",
|
|
category: "essentials",
|
|
icon: "Crop",
|
|
route: "/crop",
|
|
},
|
|
{
|
|
id: "rotate",
|
|
name: "Rotate & Flip",
|
|
description: "Rotate, flip, and straighten images",
|
|
category: "essentials",
|
|
icon: "RotateCw",
|
|
route: "/rotate",
|
|
},
|
|
{
|
|
id: "convert",
|
|
name: "Convert",
|
|
description: "Convert between image formats",
|
|
category: "essentials",
|
|
icon: "FileOutput",
|
|
route: "/convert",
|
|
},
|
|
{
|
|
id: "compress",
|
|
name: "Compress",
|
|
description: "Reduce file size by quality or target size",
|
|
category: "essentials",
|
|
icon: "Minimize2",
|
|
route: "/compress",
|
|
},
|
|
// Optimization
|
|
{
|
|
id: "strip-metadata",
|
|
name: "Remove Metadata",
|
|
description: "Remove EXIF, GPS, and camera info",
|
|
category: "optimization",
|
|
icon: "ShieldOff",
|
|
route: "/strip-metadata",
|
|
},
|
|
{
|
|
id: "edit-metadata",
|
|
name: "Edit Metadata",
|
|
description: "Edit EXIF, GPS, and camera info",
|
|
category: "optimization",
|
|
icon: "PenLine",
|
|
route: "/edit-metadata",
|
|
},
|
|
{
|
|
id: "bulk-rename",
|
|
name: "Bulk Rename",
|
|
description: "Rename multiple files with patterns",
|
|
category: "optimization",
|
|
icon: "FileEdit",
|
|
route: "/bulk-rename",
|
|
},
|
|
{
|
|
id: "image-to-pdf",
|
|
name: "Image to PDF",
|
|
description: "Combine images into a PDF document",
|
|
category: "optimization",
|
|
icon: "FileText",
|
|
route: "/image-to-pdf",
|
|
},
|
|
{
|
|
id: "favicon",
|
|
name: "Favicon Generator",
|
|
description: "Generate all favicon and app icon sizes",
|
|
category: "optimization",
|
|
icon: "Globe",
|
|
route: "/favicon",
|
|
},
|
|
// Adjustments
|
|
{
|
|
id: "adjust-colors",
|
|
name: "Adjust Colors",
|
|
description: "Brightness, contrast, exposure, saturation, temperature, sharpness, and effects",
|
|
category: "adjustments",
|
|
icon: "SlidersHorizontal",
|
|
route: "/adjust-colors",
|
|
},
|
|
{
|
|
id: "replace-color",
|
|
name: "Replace & Invert Color",
|
|
description: "Replace specific colors or invert",
|
|
category: "adjustments",
|
|
icon: "Pipette",
|
|
route: "/replace-color",
|
|
},
|
|
// AI Tools
|
|
{
|
|
id: "remove-background",
|
|
name: "Remove Background",
|
|
description: "AI-powered background removal",
|
|
category: "ai",
|
|
icon: "Eraser",
|
|
route: "/remove-background",
|
|
},
|
|
{
|
|
id: "upscale",
|
|
name: "Image Upscaling",
|
|
description: "AI super-resolution enhancement",
|
|
category: "ai",
|
|
icon: "ZoomIn",
|
|
route: "/upscale",
|
|
},
|
|
{
|
|
id: "erase-object",
|
|
name: "Object Eraser",
|
|
description: "Remove unwanted objects with AI",
|
|
category: "ai",
|
|
icon: "Wand2",
|
|
route: "/erase-object",
|
|
},
|
|
{
|
|
id: "ocr",
|
|
name: "OCR / Text Extraction",
|
|
description: "Extract text from images",
|
|
category: "ai",
|
|
icon: "ScanText",
|
|
route: "/ocr",
|
|
},
|
|
{
|
|
id: "blur-faces",
|
|
name: "Face / PII Blur",
|
|
description: "Auto-detect and blur faces and sensitive info",
|
|
category: "ai",
|
|
icon: "EyeOff",
|
|
route: "/blur-faces",
|
|
},
|
|
{
|
|
id: "smart-crop",
|
|
name: "Smart Crop",
|
|
description: "Smart subject, face, or trim-based cropping",
|
|
category: "ai",
|
|
icon: "Focus",
|
|
route: "/smart-crop",
|
|
},
|
|
// Watermark & Overlay
|
|
{
|
|
id: "watermark-text",
|
|
name: "Text Watermark",
|
|
description: "Add text watermark overlay",
|
|
category: "watermark",
|
|
icon: "Type",
|
|
route: "/watermark-text",
|
|
},
|
|
{
|
|
id: "watermark-image",
|
|
name: "Image Watermark",
|
|
description: "Overlay a logo as watermark",
|
|
category: "watermark",
|
|
icon: "Image",
|
|
route: "/watermark-image",
|
|
},
|
|
{
|
|
id: "text-overlay",
|
|
name: "Text Overlay",
|
|
description: "Add styled text to images",
|
|
category: "watermark",
|
|
icon: "TextCursorInput",
|
|
route: "/text-overlay",
|
|
},
|
|
{
|
|
id: "compose",
|
|
name: "Image Composition",
|
|
description: "Layer images with position and opacity",
|
|
category: "watermark",
|
|
icon: "Layers",
|
|
route: "/compose",
|
|
},
|
|
// Utilities
|
|
{
|
|
id: "info",
|
|
name: "Image Info",
|
|
description: "View all metadata and image properties",
|
|
category: "utilities",
|
|
icon: "Info",
|
|
route: "/info",
|
|
},
|
|
{
|
|
id: "compare",
|
|
name: "Image Compare",
|
|
description: "Side-by-side comparison of two images",
|
|
category: "utilities",
|
|
icon: "Columns2",
|
|
route: "/compare",
|
|
},
|
|
{
|
|
id: "find-duplicates",
|
|
name: "Find Duplicates",
|
|
description: "Detect duplicate and near-duplicate images",
|
|
category: "utilities",
|
|
icon: "Copy",
|
|
route: "/find-duplicates",
|
|
},
|
|
{
|
|
id: "color-palette",
|
|
name: "Color Palette",
|
|
description: "Extract dominant colors from image",
|
|
category: "utilities",
|
|
icon: "Palette",
|
|
route: "/color-palette",
|
|
},
|
|
{
|
|
id: "qr-generate",
|
|
name: "QR Code Generator",
|
|
description: "Generate QR codes from text or URLs",
|
|
category: "utilities",
|
|
icon: "QrCode",
|
|
route: "/qr-generate",
|
|
},
|
|
{
|
|
id: "barcode-read",
|
|
name: "Barcode Reader",
|
|
description: "Read QR codes and barcodes from images",
|
|
category: "utilities",
|
|
icon: "ScanLine",
|
|
route: "/barcode-read",
|
|
},
|
|
// Layout & Composition
|
|
{
|
|
id: "collage",
|
|
name: "Collage / Grid",
|
|
description: "Combine images into a grid layout",
|
|
category: "layout",
|
|
icon: "LayoutGrid",
|
|
route: "/collage",
|
|
},
|
|
{
|
|
id: "stitch",
|
|
name: "Stitch",
|
|
description: "Join images side by side or top to bottom",
|
|
category: "layout",
|
|
icon: "Columns",
|
|
route: "/stitch",
|
|
},
|
|
{
|
|
id: "split",
|
|
name: "Image Splitting",
|
|
description: "Split image into grid parts",
|
|
category: "layout",
|
|
icon: "Grid3x3",
|
|
route: "/split",
|
|
},
|
|
{
|
|
id: "border",
|
|
name: "Border & Frame",
|
|
description: "Add borders, rounded corners, shadows",
|
|
category: "layout",
|
|
icon: "Frame",
|
|
route: "/border",
|
|
},
|
|
// Format & Conversion
|
|
{
|
|
id: "svg-to-raster",
|
|
name: "SVG to Raster",
|
|
description: "Convert SVG to PNG/JPG at custom resolution",
|
|
category: "format",
|
|
icon: "FileImage",
|
|
route: "/svg-to-raster",
|
|
},
|
|
{
|
|
id: "vectorize",
|
|
name: "Image to SVG",
|
|
description: "Vectorize images using tracing",
|
|
category: "format",
|
|
icon: "PenTool",
|
|
route: "/vectorize",
|
|
},
|
|
{
|
|
id: "gif-tools",
|
|
name: "GIF Tools",
|
|
description: "Resize/crop/convert animated GIFs",
|
|
category: "format",
|
|
icon: "Film",
|
|
route: "/gif-tools",
|
|
},
|
|
{
|
|
id: "pdf-to-image",
|
|
name: "PDF to Image",
|
|
description: "Convert PDF pages to images",
|
|
category: "format",
|
|
icon: "FileOutput",
|
|
route: "/pdf-to-image",
|
|
},
|
|
// Automation
|
|
{
|
|
id: "pipeline",
|
|
name: "Pipeline Builder",
|
|
description: "Chain multiple tools into a workflow",
|
|
category: "automation",
|
|
icon: "Workflow",
|
|
route: "/pipeline",
|
|
},
|
|
{
|
|
id: "batch",
|
|
name: "Batch Processing",
|
|
description: "Apply any tool to multiple images",
|
|
category: "automation",
|
|
icon: "FolderInput",
|
|
route: "/batch",
|
|
},
|
|
];
|
|
|
|
export const SOCIAL_MEDIA_PRESETS: SocialMediaPreset[] = [
|
|
{ platform: "Instagram", name: "Post (Square)", width: 1080, height: 1080 },
|
|
{ platform: "Instagram", name: "Story / Reel", width: 1080, height: 1920 },
|
|
{ platform: "Instagram", name: "Profile Picture", width: 320, height: 320 },
|
|
{ platform: "Instagram", name: "Landscape Post", width: 1080, height: 566 },
|
|
{ platform: "Instagram", name: "Portrait Post", width: 1080, height: 1350 },
|
|
{ platform: "Twitter/X", name: "Post Image", width: 1200, height: 675 },
|
|
{ platform: "Twitter/X", name: "Header", width: 1500, height: 500 },
|
|
{ platform: "Twitter/X", name: "Profile Picture", width: 400, height: 400 },
|
|
{ platform: "Facebook", name: "Post Image", width: 1200, height: 630 },
|
|
{ platform: "Facebook", name: "Cover Photo", width: 820, height: 312 },
|
|
{ platform: "Facebook", name: "Profile Picture", width: 170, height: 170 },
|
|
{ platform: "Facebook", name: "Event Cover", width: 1920, height: 1005 },
|
|
{ platform: "YouTube", name: "Thumbnail", width: 1280, height: 720 },
|
|
{ platform: "YouTube", name: "Channel Banner", width: 2560, height: 1440 },
|
|
{ platform: "YouTube", name: "Profile Picture", width: 800, height: 800 },
|
|
{ platform: "LinkedIn", name: "Post Image", width: 1200, height: 627 },
|
|
{ platform: "LinkedIn", name: "Banner", width: 1584, height: 396 },
|
|
{ platform: "LinkedIn", name: "Profile Picture", width: 400, height: 400 },
|
|
{ platform: "TikTok", name: "Video Cover", width: 1080, height: 1920 },
|
|
{ platform: "TikTok", name: "Profile Picture", width: 200, height: 200 },
|
|
{ platform: "WhatsApp", name: "Profile Picture", width: 500, height: 500 },
|
|
{ platform: "Pinterest", name: "Pin", width: 1000, height: 1500 },
|
|
{ platform: "Threads", name: "Post Image", width: 1080, height: 1080 },
|
|
];
|
|
|
|
export interface SmartCropFacePreset {
|
|
id: string;
|
|
label: string;
|
|
multiplier: number;
|
|
}
|
|
|
|
export const SMART_CROP_FACE_PRESETS: SmartCropFacePreset[] = [
|
|
{ id: "closeup", label: "Close-up", multiplier: 1.8 },
|
|
{ id: "head-shoulders", label: "Head & Shoulders", multiplier: 2.8 },
|
|
{ id: "upper-body", label: "Upper Body", multiplier: 4.5 },
|
|
{ id: "half-body", label: "Half Body", multiplier: 7.0 },
|
|
];
|
|
|
|
export const APP_VERSION = "1.14.0";
|
|
|
|
/**
|
|
* Tool IDs that require the Python sidecar (AI/ML tools).
|
|
* Used by the frontend for progress/timeout behavior.
|
|
*/
|
|
export const PYTHON_SIDECAR_TOOLS = [
|
|
"remove-background",
|
|
"upscale",
|
|
"blur-faces",
|
|
"erase-object",
|
|
"ocr",
|
|
] as const;
|