{"id":35297747,"url":"https://github.com/maccesar/imgconvert-cli","last_synced_at":"2026-04-05T05:00:58.169Z","repository":{"id":264934582,"uuid":"866226304","full_name":"macCesar/imgconvert-cli","owner":"macCesar","description":"A command-line tool for compressing, converting, and resizing images using the powerful `sharp` library.","archived":false,"fork":false,"pushed_at":"2026-01-21T16:12:22.000Z","size":70444,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-29T08:44:34.168Z","etag":null,"topics":["format-converter","image-processing","javascript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/macCesar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-10-01T21:36:50.000Z","updated_at":"2026-01-21T16:36:49.000Z","dependencies_parsed_at":"2025-08-27T20:17:21.835Z","dependency_job_id":"6bf5e779-4e52-47d8-ba6e-f216170301ce","html_url":"https://github.com/macCesar/imgconvert-cli","commit_stats":null,"previous_names":["maccesar/imgconvert-cli"],"tags_count":42,"template":false,"template_full_name":null,"purl":"pkg:github/macCesar/imgconvert-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macCesar%2Fimgconvert-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macCesar%2Fimgconvert-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macCesar%2Fimgconvert-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macCesar%2Fimgconvert-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/macCesar","download_url":"https://codeload.github.com/macCesar/imgconvert-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macCesar%2Fimgconvert-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31424931,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T02:22:46.605Z","status":"ssl_error","status_checked_at":"2026-04-05T02:22:33.263Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["format-converter","image-processing","javascript"],"created_at":"2025-12-30T16:35:21.348Z","updated_at":"2026-04-05T05:00:58.161Z","avatar_url":"https://github.com/macCesar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# imgconvert-cli\n\n\u003cdiv align=\"center\"\u003e\n\n  ![npm version](https://img.shields.io/npm/v/imgconvert-cli)\n  ![Node.js Version](https://img.shields.io/node/v/imgconvert-cli)\n  ![downloads](https://img.shields.io/npm/dm/imgconvert-cli)\n  ![license](https://img.shields.io/npm/l/imgconvert-cli)\n  ![test coverage](https://img.shields.io/badge/tests-74%20passing-brightgreen)\n  ![GitHub Stars](https://img.shields.io/github/stars/macCesar/imgconvert-cli)\n\n\u003c/div\u003e\n\n`imgconvert-cli` is a command-line tool for compressing, converting, and resizing images using the `sharp` library. It supports JPEG, PNG, WebP, AVIF, TIFF, and GIF, with options for quality, background color, resize strategies, and batch processing.\n\n## Quick start\n\n```bash\n# Install globally\nnpm install -g imgconvert-cli\n\n# Compress images (preserves original format)\nimgconvert my-images\n\n# Convert to WebP with 80% quality\nimgconvert my-images -f webp -q 80\n\n# Advanced resizing with cover strategy (crops to fill dimensions)\nimgconvert photo.jpg --fit cover --position center -w 400 -h 400 -f webp\n\n# Manual cropping: extract specific region then resize\nimgconvert photo.jpg --crop 100,50,800,600 -w 400 -h 300 -f webp\n\n# Canvas resize: maintain original image, add transparent padding\nimgconvert photo.png --canvas -h 1660\nimgconvert design.png --canvas -w 800 -h 600 -f webp\n\n# Custom file naming and batch renaming\nimgconvert photo.jpg --name \"hero-banner\" -f webp\nimgconvert photos --rename \"lowercase,replace-spaces,prefix:web-\" -f webp\n\n# Generate mobile app assets (all configurations)\nimgconvert source-images -p alloy\n\n# Generate specific mobile app assets (user-defined configurations)\nimgconvert -p alloy:your-config-name\nimgconvert -p alloy:another-config\n```\n\n## Common use cases\n\n- Batch convert images to WebP for faster loading\n- Consistent square thumbnails with `--fit cover` and `--position`\n- Crop to exact dimensions with `--crop`, then resize\n- Extend canvas without scaling the image using `--canvas`\n- Resize PNGs without losing transparency\n- Generate multi-resolution assets for iOS/Android with the Titanium Alloy preset\n- Update only specific asset categories with `imgconvert -p alloy:config-name`\n- Convert to TIFF for print\n- Process entire directories at once\n- Batch rename files: lowercase, replace spaces, add prefixes/suffixes\n\n## Performance\n\nTypical compression results:\n- JPEG to WebP: 25-35% size reduction\n- PNG to WebP: 40-60% size reduction\n- Batch processing: ~50-100 images/second\n- Handles large batches without memory issues\n\n## Project stats\n\n- Platforms: macOS, Linux, Windows\n- Bundle size: ~45KB (excluding Sharp)\n- Tests: 74 passing\n- Dependencies: 3 (sharp, minimist, chalk)\n\n## Table of Contents\n- [Features](#features)\n- [Installation](#installation)\n- [Basic Usage](#basic-usage)\n- [Options](#options)\n- [File Naming and Batch Renaming](#file-naming-and-batch-renaming)\n- [Examples](#examples)\n- [File Extension Behavior](#file-extension-behavior)\n- [Presets](#presets)\n- [Custom Presets](#custom-presets)\n- [Alloy Preset](#alloy-preset)\n- [Configuration File](#configuration-file)\n- [Debug Mode](#debug-mode)\n- [Troubleshooting](#troubleshooting)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Features\n\n- Compress images while maintaining quality\n- Convert between JPEG, PNG, WebP, AVIF, TIFF, and GIF\n- Multiple resize strategies: cover, contain, fill, inside, outside\n- Position control when cropping (center, top, bottom, left, right, corners)\n- Manual cropping with precise coordinates\n- Process single files or entire directories\n- Preserves original file extensions when no format conversion is specified\n- Custom file naming and batch renaming (enumerate, lowercase, replace spaces, prefix, suffix)\n- Adjustable quality from 1-100\n- Configurable background color for transparency handling\n- Convert to all supported formats in one command with `-f all`\n- Replace originals in-place with `--replace-originals`\n- Built-in presets: web, print, thumbnail, alloy\n- Custom output directory with `-o`\n- Debug mode with `-d` for troubleshooting\n\n## How It Works\n\n- Accepts a single file or a directory as input\n- Uses `sharp` to apply compression, format conversion, resizing, and optional background color\n- **Preserves original file extensions** when no format is specified (e.g., `image.jpg` → `image.jpg`)\n- Only changes file extension when explicitly converting formats (e.g., `image.jpg -f webp` → `image.webp`)\n- Outputs to a `converted` subfolder by default, or replaces original files if `--replace-originals` is used\n- Resizing preserves aspect ratio unless both width and height are specified\n\n## Installation\n\n### Prerequisites\n- Node.js 14+\n- NPM or Yarn\n\n### Install\n```bash\nnpm install -g imgconvert-cli\n# or\nyarn global add imgconvert-cli\n```\n\n### Verify Installation\n```bash\nimgconvert --version\n```\n\n## Basic Usage\n\n```bash\nimgconvert \u003csource_path\u003e\n```\n\n- `\u003csource_path\u003e`: The path to the image file or directory containing the images you want to process. This is a required positional argument.\n\n\u003e When you don't specify `-f`, each output image keeps its original extension:\n\u003e - `image.jpg` → `image.jpg` (compressed but same format)\n\u003e - `image.png` → `image.png` (compressed but same format)\n\u003e\n\u003e The file extension only changes when you explicitly specify a different format with `-f`.\n\n## Options\n\n\n| Option                | Alias | Description                                                                             | Default                                    |\n| --------------------- | ----- | --------------------------------------------------------------------------------------- | ------------------------------------------ |\n| `--format`            | `-f`  | Output format: `jpeg`, `png`, `webp`, `avif`, `tiff`, `gif`, `all`                      | Original format                            |\n| `--quality`           | `-q`  | Quality (1-100)                                                                         | 85                                         |\n| `--background`        | `-b`  | Background color when converting from transparent formats to non-transparent formats    | Transparent for PNG/WebP, #ffffff for JPEG |\n| `--width`             | `-w`  | Output width in pixels                                                                  | -                                          |\n| `--height`            | `-h`  | Output height in pixels                                                                 | -                                          |\n| `--output`            | `-o`  | Output directory                                                                        | Same as source                             |\n| `--preset`            | `-p`  | Apply preset: `web`, `print`, `thumbnail`, `alloy`                                      | -                                          |\n| `--fit`               | -     | Resize strategy: `cover`, `contain`, `fill`, `inside`, `outside`                        | `contain`                                  |\n| `--position`          | -     | Crop position: `center`, `top`, `bottom`, `left`, `right`, corners                      | `center`                                   |\n| `--crop`              | -     | Manual crop coordinates: `left,top,width,height`                                        | -                                          |\n| `--canvas`            | -     | Resize canvas instead of image (maintains original, adds padding)                       | `false`                                    |\n| `--name`              | `-n`  | Custom filename for single file processing                                              | -                                          |\n| `--rename`            | -     | Batch rename strategy: `enumerate`, `lowercase`, `replace-spaces`, `prefix:`, `suffix:` | -                                          |\n| `--replace-originals` | -     | Replace original files                                                                  | `false`                                    |\n| `--debug`             | `-d`  | Enable debug mode                                                                       | `false`                                    |\n| `--version`           | `-v`  | Show version                                                                            | -                                          |\n| `--help`              | `-H`  | Show help message                                                                       | -                                          |\n\n## Advanced resize and crop control\n\nProcessing order: Manual Crop → Resize → Format Conversion\n\n### Fit Strategies (`--fit`)\n\nControls how images are resized when both width and height are specified:\n\n| Strategy  | Behavior                           | Use Case                | Aspect Ratio |\n| --------- | ---------------------------------- | ----------------------- | ------------ |\n| `contain` | Shrink to fit, letterbox if needed | Preserve entire image   | Preserved    |\n| `cover`   | Crop to fill dimensions exactly    | Hero images, thumbnails | Preserved    |\n| `fill`    | Stretch to exact dimensions        | Icons, backgrounds      | Ignored      |\n| `inside`  | Only shrink, never enlarge         | High-res source images  | Preserved    |\n| `outside` | Only enlarge, never shrink         | Upscaling small images  | Preserved    |\n\n### Position Control (`--position`)\n\nWhen using `--fit cover`, `--fit contain`, or `--canvas`, controls which part of the image to preserve or focus on:\n\n| Position       | Description                  | Best For                 |\n| -------------- | ---------------------------- | ------------------------ |\n| `center`       | Focus on center (default)    | General purpose          |\n| `top`          | Focus on top edge            | Portraits, faces         |\n| `bottom`       | Focus on bottom edge         | Architecture             |\n| `left`         | Focus on left edge           | Portraits (left-facing)  |\n| `right`        | Focus on right edge          | Portraits (right-facing) |\n| `top left`     | Focus on top-left corner     | Documents, logos         |\n| `top right`    | Focus on top-right corner    | UI screenshots           |\n| `bottom left`  | Focus on bottom-left corner  | Signatures               |\n| `bottom right` | Focus on bottom-right corner | Watermarks               |\n\n### Manual Cropping (`--crop`)\n\nExtract specific regions before resizing:\n\n- **Format**: `left,top,width,height` (all in pixels)\n- **Example**: `--crop 100,50,800,600` crops 800x600 region starting at (100,50)\n- **Workflow**: Cropping is applied first, then resizing with fit/position options\n\n### Canvas resize vs image resize (`--canvas`)\n\n#### Standard Resize (Default)\n- **Use case**: Traditional image resizing\n- **Behavior**: Scales the image proportionally\n- **Transparency**: Preserves existing transparency\n\n```bash\nimgconvert photo.png -h 1660\n# 1024x1536 → 1107x1660 (proportional scaling)\n```\n\n#### Canvas Resize (`--canvas`)\n- **Use case**: Design layouts, maintaining exact canvas sizes\n- **Behavior**: Maintains original image, adds padding to reach target dimensions\n- **Transparency**: Adds transparent padding for PNG/WebP, white for JPEG\n- **Position Control**: Use `--position` to control where the image is placed within the expanded canvas\n\n```bash\nimgconvert photo.png --canvas -h 1660\n# 1024x1536 → 1024x1660 (original image centered + transparent padding)\n\nimgconvert photo.png --canvas -h 1660 --position top\n# 1024x1536 → 1024x1660 (original image at top + transparent padding at bottom)\n\nimgconvert photo.png --canvas -h 1660 --position bottom\n# 1024x1536 → 1024x1660 (original image at bottom + transparent padding at top)\n\nimgconvert photo.png --canvas -h 1660 -b \"#ff0000\"\n# 1024x1536 → 1024x1660 (original image + red padding)\n```\n\n| Aspect               | Standard Resize         | Canvas Resize (`--canvas`) |\n| -------------------- | ----------------------- | -------------------------- |\n| **Image scaling**    | ✅ Scales proportionally | ❌ Maintains original size  |\n| **Exact dimensions** | ❌ Respects aspect ratio | ✅ Exact target dimensions  |\n| **Transparency**     | Preserves existing      | ✅ Adds transparent padding |\n| **Position control** | Via `--position`        | ✅ Via `--position` (NEW)   |\n| **Use case**         | Photo resizing          | Design layouts, mockups    |\n\n## File naming and batch renaming\n\n### Single file naming (`--name`, `-n`)\n\nRename individual files during processing:\n\n```bash\nimgconvert photo.jpg --name \"hero-image\" -f webp\n# Output: hero-image.webp\n```\n\n**Important**: The `--name` option only works with single files, not directories.\n\n### Batch renaming strategies (`--rename`)\n\nApply systematic renaming to multiple files:\n\n| Strategy         | Description                 | Example Input  | Example Output    |\n| ---------------- | --------------------------- | -------------- | ----------------- |\n| `enumerate`      | Add sequential numbers      | `photo.jpg`    | `001-photo.jpg`   |\n| `lowercase`      | Convert to lowercase        | `MyPhoto.JPG`  | `myphoto.jpg`     |\n| `replace-spaces` | Replace spaces with hyphens | `my photo.png` | `my-photo.png`    |\n| `prefix:text`    | Add prefix to filename      | `image.jpg`    | `thumb-image.jpg` |\n| `suffix:text`    | Add suffix to filename      | `image.jpg`    | `image-small.jpg` |\n\n### Combining strategies\n\nMultiple rename strategies can be combined by separating them with commas:\n\n```bash\nimgconvert photos --rename \"lowercase,replace-spaces,prefix:web-\"\n# \"My Photo.jpg\" → \"web-my-photo.jpg\"\n\nimgconvert images --rename \"prefix:gallery-,enumerate\"\n# \"photo.jpg\" → \"gallery-001-photo.jpg\"\n```\n\nStrategies are applied left to right, so the result matches the order you write them.\n\n## Examples\n\n### Basic operations\n\n1. **Compress images without changing format (preserves extensions):**\n   ```bash\n   imgconvert image.jpg      # → image.jpg (compressed)\n   imgconvert image.png      # → image.png (compressed)\n   ```\n\n2. **Compress all images in directory (preserves original formats):**\n   ```bash\n   imgconvert source_folder  # Each file keeps its original extension\n   ```\n\n3. **Convert to different format (changes extension):**\n   ```bash\n   imgconvert image.jpg -f webp -q 75    # → image.webp\n   imgconvert image.png -f jpeg          # → image.jpeg\n   ```\n\n### Resizing and cropping\n\n4. **Smart resizing strategies:**\n   ```bash\n   # Cover strategy: crop to fill exact dimensions\n   imgconvert photo.jpg --fit cover -w 400 -h 400\n\n   # Contain strategy: fit inside dimensions (default)\n   imgconvert photo.jpg --fit contain -w 400 -h 400\n\n   # Fill strategy: stretch to exact dimensions\n   imgconvert photo.jpg --fit fill -w 400 -h 400\n   ```\n\n5. **Control cropping position with cover strategy:**\n   ```bash\n   # Keep the top part when cropping\n   imgconvert portrait.jpg --fit cover --position top -w 300 -h 300\n\n   # Keep the center (default)\n   imgconvert photo.jpg --fit cover --position center -w 300 -h 300\n\n   # Keep specific corners\n   imgconvert image.jpg --fit cover --position \"top left\" -w 400 -h 400\n   ```\n\n6. **Control positioning with contain strategy (letterboxing):**\n   ```bash\n   # Position image at top of canvas when letterboxing\n   imgconvert wide-image.jpg --fit contain --position top -w 400 -h 400\n\n   # Position image at bottom-right when letterboxing\n   imgconvert landscape.jpg --fit contain --position \"bottom right\" -w 600 -h 600\n   ```\n\n7. **Manual cropping before resizing:**\n   ```bash\n   # Crop specific region then resize\n   imgconvert image.png --crop 100,50,300,200 -w 200 -h 150\n\n   # Crop and convert format\n   imgconvert photo.jpg --crop 0,0,500,500 --fit cover -w 300 -h 300 -f webp\n   ```\n\n8. **Canvas resizing (maintain original image, add padding):**\n   ```bash\n   # Resize canvas to larger dimensions with transparent padding\n   imgconvert photo.png --canvas -h 1660\n   # Original 1024x1536 → Output 1024x1660 with transparent padding (centered)\n\n   # Control position within the expanded canvas\n   imgconvert photo.png --canvas -h 1660 --position top\n   # Original 1024x1536 → Output 1024x1660 with image at top, transparent padding at bottom\n\n   imgconvert photo.png --canvas -h 1660 --position bottom\n   # Original 1024x1536 → Output 1024x1660 with image at bottom, transparent padding at top\n\n   # Resize canvas with custom background color\n   imgconvert photo.png --canvas -h 1660 -b \"#ffffff\"\n   # Adds white padding instead of transparent\n\n   # Resize canvas to exact dimensions\n   imgconvert image.jpg --canvas -w 800 -h 600 -f png\n   # Maintains original image centered, adds transparent padding to reach 800x600\n   ```\n\n### File naming and renaming\n\n9. **Custom naming for single files:**\n   ```bash\n   # Rename during conversion\n   imgconvert hero-photo.jpg --name \"main-banner\" -f webp\n   # Output: main-banner.webp\n\n   # Custom name with resizing\n   imgconvert profile.png --name \"avatar\" --fit cover -w 200 -h 200\n   # Output: avatar.png\n   ```\n\n10. **Batch renaming strategies:**\n   ```bash\n   # Add sequential numbers\n   imgconvert photos --rename enumerate -f webp\n   # photo1.jpg → 001-photo1.webp, photo2.jpg → 002-photo2.webp\n\n   # Convert to lowercase and replace spaces\n   imgconvert \"My Photos\" --rename \"lowercase,replace-spaces\"\n   # \"My Photo.JPG\" → \"my-photo.jpg\"\n\n   # Add prefix for organization\n   imgconvert thumbnails --rename \"prefix:thumb-\" -w 150 -h 150\n   # image.jpg → thumb-image.jpg\n   ```\n\n9. **Advanced renaming combinations:**\n   ```bash\n   # Multiple strategies for web optimization\n   imgconvert uploads --rename \"lowercase,replace-spaces,suffix:-optimized\" -f webp -q 80\n   # \"Product Photo.png\" → \"product-photo-optimized.webp\"\n\n   # Enumerated thumbnails with prefix\n   imgconvert gallery --rename \"prefix:gallery-,enumerate\" --fit cover -w 300 -h 300\n   # photo.jpg → gallery-001-photo.jpg\n   ```\n\n### Real-world examples\n\n10. **Web development:**\n    ```bash\n    # Social media thumbnails with organized naming\n    imgconvert profiles --fit cover --position top -w 150 -h 150 -f webp --rename \"prefix:profile-,enumerate\"\n\n    # Product images with consistent dimensions and clean filenames\n    imgconvert products --fit contain -w 800 -h 600 -f webp -q 90 --rename \"lowercase,replace-spaces\"\n\n    # Hero banners with descriptive names\n    imgconvert heroes --fit cover --position center -w 1920 -h 800 -f webp --rename \"suffix:-hero\"\n    ```\n\n11. **Mobile app assets with systematic naming:**\n    ```bash\n    # Square app icons with size indicators\n    imgconvert icons --fit cover --position center -w 512 -h 512 -f png --rename \"suffix:-512\"\n\n    # Profile pictures with enumeration\n    imgconvert avatars --fit cover --position top -w 200 -h 200 -f webp --rename \"prefix:avatar-,enumerate\"\n    ```\n\n12. **E-commerce and content management:**\n    ```bash\n    # Product catalog with clean, SEO-friendly names\n    imgconvert \"Product Photos\" --rename \"lowercase,replace-spaces,prefix:product-\" -f webp -q 85\n    # \"Blue Shirt Medium.jpg\" → \"product-blue-shirt-medium.webp\"\n\n    # Blog post images with consistent naming\n    imgconvert blog-images --rename \"lowercase,replace-spaces,suffix:-post\" -w 800 -q 80\n    # \"My Great Article Photo.png\" → \"my-great-article-photo-post.png\"\n    ```\n\n    # Profile pictures\n    imgconvert avatars --fit cover --position top -w 200 -h 200 -f webp\n    ```\n\n12. **Use alloy preset with platform-specific formats:**\n    ```bash\n    imgconvert source_folder -p alloy\n    # Generates images for ALL configurations (comics, thumbs-comics, baby, thumbs-baby)\n    ```\n\n13. **Process specific alloy configurations (user-defined):**\n    ```bash\n    imgconvert -p alloy:your-cards-config\n    # Processes ONLY the 'your-cards-config' configuration (both Android and iPhone)\n    # Note: 'your-cards-config' must be defined in your .imgconverter.config.json\n\n    imgconvert -p alloy:your-thumbnails-config\n    # Processes ONLY the 'your-thumbnails-config' configuration\n    # Note: 'your-thumbnails-config' must be defined in your .imgconverter.config.json\n\n    imgconvert -p alloy:your-icons-config\n    # Processes ONLY the 'your-icons-config' configuration\n    # Note: 'your-icons-config' must be defined in your .imgconverter.config.json\n    ```\n\n14. **Override preset settings with CLI arguments:**\n    ```bash\n    imgconvert source_folder -p alloy -f png -q 95\n    # CLI arguments override preset: both Android and iPhone will use PNG at 95% quality\n\n    imgconvert -p alloy:your-cards-config -q 90\n    # Only 'your-cards-config' configuration with 90% quality override\n    # Note: 'your-cards-config' must be defined in your .imgconverter.config.json\n    ```\n\n15. **Use preset settings with partial CLI override:**\n    ```bash\n    imgconvert source_folder -p alloy -q 80\n    # Only quality is overridden: Android uses WebP, iPhone uses PNG, both at 80% quality\n\n    imgconvert -p alloy:your-config-name -f webp\n    # Only your-config-name configuration, forced to WebP format for both platforms\n    # Note: 'your-config-name' must be defined in your .imgconverter.config.json\n    ```\n\n16. **Extract and optimize specific image regions with manual cropping:**\n    ```bash\n    # Extract a product from a larger photo and create web-optimized thumbnails\n    imgconvert product-photo.jpg --crop 200,150,600,800 -w 300 -h 400 -f webp -q 85\n\n    # Create hero image by cropping center portion from high-res photo\n    imgconvert landscape.jpg --crop 500,100,1920,800 --fit cover -w 1200 -h 500 -f webp\n\n    # Extract faces from group photos for profile pictures\n    imgconvert group-photo.jpg --crop 350,200,500,500 --fit cover -w 150 -h 150 -f webp\n    ```\n\n### Utility operations\n\n18. **Specify a custom output directory:**\n    ```bash\n    imgconvert source_folder -o custom_output_directory\n    ```\n\n19. **Enable debug mode:**\n    ```bash\n    imgconvert source_folder -d\n    ```\n\n20. **Check the version of the module:**\n    ```bash\n    imgconvert --version\n    ```\n\n21. **Show help message:**\n    ```bash\n    imgconvert --help\n    ```\n\n## File extension behavior\n\n### Preserve original extensions\nWhen no format is specified with `-f`, the original file extension is preserved:\n\n| Input       | Command                | Output      |\n| ----------- | ---------------------- | ----------- |\n| `logo.png`  | `imgconvert logo.png`  | `logo.png`  |\n| `icon.webp` | `imgconvert icon.webp` | `icon.webp` |\n| `photo.jpg` | `imgconvert photo.jpg` | `photo.jpg` |\n\n### Format conversion changes extensions\nWhen using `-f` to specify a format, the extension changes accordingly:\n\n| Input       | Command                        | Output       |\n| ----------- | ------------------------------ | ------------ |\n| `logo.png`  | `imgconvert logo.png -f jpeg`  | `logo.jpeg`  |\n| `icon.webp` | `imgconvert icon.webp -f png`  | `icon.png`   |\n| `photo.jpg` | `imgconvert photo.jpg -f webp` | `photo.webp` |\n\n\u003e **Tip:** The extension only changes when you explicitly use `-f`.\n\n## Presets\n\nPresets are predefined configurations for common use cases:\n\n- **web**: Optimized for the web (`webp`, quality `80`). Optionally defines a `source` path.\n- **print**: High-quality output (`tiff`, quality `100`). Optionally defines a `source` path.\n- **thumbnail**: Small previews (`png`, quality `60`, 150x150). Optionally defines a `source` path.\n- **square-thumbs**: Consistent square thumbnails (`webp`, quality `80`, 300x300). Optionally defines a `source` path.\n- **hero-images**: High-quality hero images (`webp`, quality `85`, 1920x1080). Optionally defines a `source` path.\n- **alloy**: For Titanium SDK. Generates scaled images for Android and iOS at all required densities. Supports a single-source legacy format and a multi-configuration format (e.g., cards, thumbnails, icons with independent settings). Process everything with `-p alloy` or target one group with `-p alloy:configName`.\n\n## Custom Presets\n\nYou can define your own presets in `.imgconverter.config.json`.\n\n### Example\n\n```json\n{\n  \"presets\": {\n    \"instagram-post\": {\n      \"width\": 1080,\n      \"height\": 1080,\n      \"quality\": 85,\n      \"format\": \"jpeg\",\n      \"background\": \"#ffffff\"\n    },\n    \"email-newsletter\": {\n      \"width\": 600,\n      \"quality\": 70,\n      \"format\": \"jpeg\",\n      \"output\": \"email/assets\",\n      \"source\": \"content/images\"\n    },\n    \"product-catalog\": {\n      \"width\": 800,\n      \"height\": 800,\n      \"quality\": 90,\n      \"format\": \"webp\",\n      \"background\": \"#ffffff\"\n    }\n  }\n}\n```\n\n### Usage\n\n```bash\n# Use your custom presets\nimgconvert photos -p instagram-post\nimgconvert products -p product-catalog\nimgconvert banner.png -p email-newsletter\n\n# Override preset settings with CLI arguments\nimgconvert photos -p instagram-post -q 95  # Uses Instagram preset but with 95% quality\n\n# Use selective configuration with custom alloy presets\nimgconvert -p alloy:your-game-cards    # Process only your-game-cards configuration\nimgconvert -p alloy:your-config-name -q 90  # Process only your-config-name with custom quality\n# Note: These configurations must be defined in your .imgconverter.config.json\n```\n\n### Key points\n\n- Presets can include source and output paths\n- CLI arguments always override preset values\n- Supports all parameters: quality, format, width, height, background, source, output, replace-originals\n\nSee [custom_presets.md](custom_presets.md) for more examples.\n\n## Comparison\n\n| Feature                 | imgconvert-cli | ImageMagick | Sharp CLI |\n| ----------------------- | -------------- | ----------- | --------- |\n| Easy Setup              | ✅              | ❌           | ✅         |\n| Batch Processing        | ✅              | ✅           | ❌         |\n| Mobile Presets          | ✅              | ❌           | ❌         |\n| Custom Presets          | ✅              | ❌           | ❌         |\n| Config File             | ✅              | ❌           | ❌         |\n| Extension Preservation  | ✅              | ❌           | ❌         |\n| Multi-Format Output     | ✅              | ✅           | ❌         |\n| **Comprehensive Tests** | **✅**          | **❌**       | **❌**     |\n\n## Alloy preset\n\nThe `alloy` preset generates scaled images for Titanium Alloy apps, producing all required density variants for Android and iOS from a single set of source images.\n\n- Backward compatible with existing alloy configurations\n- Source images should be 4x resolution (the tool scales down from there)\n- Generates Android density folders (`res-mdpi` through `res-xxxhdpi`) and iOS `@2x`/`@3x` naming\n- Per-configuration quality and format settings with proper precedence\n- Scale factors are fixed to Titanium standards and cannot be changed\n- `width` and `height` parameters are ignored (scaling is based on fixed factors)\n- Supports multiple image groups (cards, thumbnails, icons) in a single command\n- Each configuration can have its own source directory and output path\n- Target a specific configuration with `alloy:configName`\n\n### Selective configuration processing\n\nYou can target individual configurations instead of processing everything:\n\n- Process only what changed, saving time during development\n- Update specific asset categories in CI/CD pipelines\n- Test one configuration without waiting for all assets to rebuild\n- Add a new category and process just that one\n\n**Examples:**\n```bash\n# Process all configurations (default behavior)\nimgconvert -p alloy\n\n# Process only your custom assets configuration\nimgconvert -p alloy:your-config-name\n\n# Process only your thumbnail variants (user-defined configurations)\nimgconvert -p alloy:your-thumbs-config1\nimgconvert -p alloy:your-thumbs-config2\n\n# Perfect for adding new categories\nimgconvert -p alloy:your-new-category  # Only process your custom 'new-category' configuration\n# Note: All configuration names must be defined in your .imgconverter.config.json\n```\n\n### Scale factors\n\nThese are fixed to match Titanium platform standards:\n- **iOS**: 1x, 2x, 3x\n- **Android**: res-mdpi (1x), res-hdpi (1.5x), res-xhdpi (2x), res-xxhdpi (3x), res-xxxhdpi (4x)\n\n\u003e Scale factors cannot be customized. They match what Titanium expects.\n\n### Usage\n\n#### Process all configurations:\n```bash\n# Legacy format (single android/iphone configuration)\nimgconvert source-images -p alloy\n\n# Multi-configuration format (all configuration groups)\nimgconvert -p alloy\n```\n\n#### Process a specific configuration:\n```bash\n# Process only your custom configuration\nimgconvert -p alloy:your-config-name\n\n# Process only your custom thumbnail configurations\nimgconvert -p alloy:your-thumbs-config1\nimgconvert -p alloy:your-thumbs-config2\n\n# Process only your custom configuration\nimgconvert -p alloy:another-config-name\n# Note: All configuration names must be defined in your .imgconverter.config.json\n```\n\n#### Single configuration (legacy format):\n```bash\nimgconvert source-images -p alloy\n```\n\n#### Multi-configuration format:\n```bash\nimgconvert -p alloy\n```\n\u003e With multi-configuration format, all groups are processed from their respective source directories. Use `-p alloy:configName` to target one.\n\n\u003e `width` and `height` are ignored with the alloy preset. Images are scaled based on fixed factors.\n\n### Output for Alloy (Android \u0026 iPhone)\n\nWhen using the `alloy` preset, the output follows this structure:\n\n- Android: `\u003cbase\u003e/app/assets/android/images`\n- iPhone: `\u003cbase\u003e/app/assets/iphone/images`\n\n**Output directory precedence:**\n\n| Priority | Condition                               | Output base (`\u003cbase\u003e`)                            |\n| -------- | --------------------------------------- | ------------------------------------------------- |\n| 1        | `-o /path/to/project` specified         | `/path/to/project`                                |\n| 2        | `tiapp.xml` exists in current directory | Current working directory (Titanium project root) |\n| 3        | No `-o` and no `tiapp.xml` in CWD       | Same directory as the input file                  |\n\n**Examples:**\n\n```bash\n# Inside a Titanium project (tiapp.xml exists in CWD)\ncd ~/Developer/my-titanium-app\nimgconvert ~/Desktop/logo.png -p alloy\n# Output: ~/Developer/my-titanium-app/app/assets/android/images/...\n\n# With explicit output directory\nimgconvert ~/Desktop/logo.png -p alloy -o ~/Developer/my-titanium-app\n# Output: ~/Developer/my-titanium-app/app/assets/android/images/...\n\n# Outside a Titanium project, no -o flag\ncd ~/Downloads\nimgconvert ~/Desktop/logo.png -p alloy\n# Output: ~/Desktop/app/assets/android/images/...\n```\n\nYou only need to specify the relative subfolder (without leading or trailing slashes, e.g. `thumbs/baby`) as the `output` in the preset configuration. The script will generate the correct structure for each density:\n\n**Correct usage:**\n\n```\n\"output\": \"thumbs/baby\"\n```\n\n**Do NOT use:**\n- `/thumbs/baby`\n- `thumbs/baby/`\n- `/thumbs/baby/`\n\n**Android Example:**\n\n```\napp/assets/android/images/res-mdpi/thumbs/baby/logo.png\napp/assets/android/images/res-hdpi/thumbs/baby/logo.png\napp/assets/android/images/res-xhdpi/thumbs/baby/logo.png\napp/assets/android/images/res-xxhdpi/thumbs/baby/logo.png\napp/assets/android/images/res-xxxhdpi/thumbs/baby/logo.png\n```\n\n**iPhone Example:**\n\n```\napp/assets/iphone/images/thumbs/baby/logo.png\napp/assets/iphone/images/thumbs/baby/logo@2x.png\napp/assets/iphone/images/thumbs/baby/logo@3x.png\n```\n\nYou do **not** need to specify the full output path, just the subfolder as shown above. The script will handle the rest.\n\n### Preset source folders\n\nTwo configuration formats are supported:\n\n#### Legacy format (single source per platform)\n\n```json\n\"presets\": {\n  \"alloy\": {\n    \"android\": {\n      \"output\": \"thumbs/baby\",\n      \"source\": \"android-source-folder\"\n    },\n    \"iphone\": {\n      \"output\": \"thumbs/baby\",\n      \"source\": \"iphone-source-folder\"\n    }\n  }\n}\n```\n\n\u003e Scale factors are applied automatically. The `scales` property is no longer supported.\n\n#### Multi-configuration format (recommended)\n\n```json\n\"presets\": {\n  \"alloy\": {\n    \"cards\": {\n      \"android\": {\n        \"quality\": 90,\n        \"format\": \"webp\",\n        \"source\": \"originals\",\n        \"output\": \"cards/baby\"\n      },\n      \"iphone\": {\n        \"quality\": 90,\n        \"format\": \"webp\",\n        \"source\": \"originals\",\n        \"output\": \"cards/baby\"\n      }\n    },\n    \"thumbs\": {\n      \"android\": {\n        \"quality\": 80,\n        \"format\": \"webp\",\n        \"output\": \"thumbs/baby\",\n        \"source\": \"original-thumbs\"\n      },\n      \"iphone\": {\n        \"quality\": 80,\n        \"format\": \"webp\",\n        \"output\": \"thumbs/baby\",\n        \"source\": \"original-thumbs\"\n      }\n    },\n    \"icons\": {\n      \"android\": {\n        \"quality\": 95,\n        \"format\": \"png\",\n        \"output\": \"icons\",\n        \"source\": \"icons-4x\"\n      },\n      \"iphone\": {\n        \"quality\": 95,\n        \"format\": \"png\",\n        \"output\": \"icons\",\n        \"source\": \"icons-4x\"\n      }\n    }\n  }\n}\n```\n\nThe tool auto-detects which format you're using. Each group can have its own quality, format, source, and output.\n\nThen run:\n\n```bash\nimgconvert -p alloy\n```\n\nThis will:\n1. Process each configuration group sequentially\n2. Show progress for each configuration and platform\n3. Show detailed debug info when using `-d`\n4. Auto-detect legacy vs multi-configuration format\n\n**Multi-configuration alloy output:**\n```\nProcessing configuration: cards\n  Processing android from: originals\n  Processing iphone from: originals\n\nProcessing configuration: thumbs\n  Processing android from: original-thumbs\n  Processing iphone from: original-thumbs\n\nProcessed files:\n - app/assets/android/images/res-mdpi/cards/baby/card1.webp (config: cards, platform: android, scale: res-mdpi)\n - app/assets/android/images/res-hdpi/cards/baby/card1.webp (config: cards, platform: android, scale: res-hdpi)\n - app/assets/iphone/images/cards/baby/card1.webp (config: cards, platform: iphone, scale: 1x)\n - app/assets/iphone/images/cards/baby/card1@2x.webp (config: cards, platform: iphone, scale: 2x)\n - app/assets/android/images/res-mdpi/thumbs/baby/thumb1.webp (config: thumbs, platform: android, scale: res-mdpi)\n ...\n\nProcessing complete! Summary:\n  - Processed files: 24\n  - Total original size: 2.45 MB\n  - Total new size: 0.89 MB\n  - Total savings: 63.67%\n  - Duration: 1.24 seconds\n```\n\n### Example: game development workflow\n\nSay you're building a card game with this directory structure:\n\n```\nmy-game/\n├── originals/          # 4x resolution card images\n│   ├── card1.png\n│   ├── card2.png\n│   └── card3.png\n├── original-thumbs/    # 4x resolution thumbnail images\n│   ├── card1.png\n│   ├── card2.png\n│   └── card3.png\n├── icons-4x/           # 4x resolution icon images\n│   ├── star.png\n│   ├── coin.png\n│   └── heart.png\n└── .imgconverter.config.json\n```\n\nWith this `.imgconverter.config.json`:\n\n```json\n{\n  \"presets\": {\n    \"alloy\": {\n      \"cards\": {\n        \"android\": {\n          \"quality\": 90,\n          \"format\": \"webp\",\n          \"source\": \"originals\",\n          \"output\": \"cards/baby\"\n        },\n        \"iphone\": {\n          \"quality\": 90,\n          \"format\": \"webp\",\n          \"source\": \"originals\",\n          \"output\": \"cards/baby\"\n        }\n      },\n      \"thumbs\": {\n        \"android\": {\n          \"quality\": 80,\n          \"format\": \"webp\",\n          \"output\": \"thumbs/baby\",\n          \"source\": \"original-thumbs\"\n        },\n        \"iphone\": {\n          \"quality\": 80,\n          \"format\": \"webp\",\n          \"output\": \"thumbs/baby\",\n          \"source\": \"original-thumbs\"\n        }\n      },\n      \"icons\": {\n        \"android\": {\n          \"quality\": 95,\n          \"format\": \"png\",\n          \"output\": \"icons\",\n          \"source\": \"icons-4x\"\n        },\n        \"iphone\": {\n          \"quality\": 95,\n          \"format\": \"png\",\n          \"output\": \"icons\",\n          \"source\": \"icons-4x\"\n        }\n      }\n    }\n  }\n}\n```\n\nOne command:\n\n```bash\nimgconvert -p alloy\n```\n\nGenerates:\n\n```\napp/\n└── assets/\n    ├── android/\n    │   └── images/\n    │       ├── res-mdpi/\n    │       │   ├── cards/baby/card1.webp (1x)\n    │       │   ├── thumbs/baby/card1.webp (1x)\n    │       │   └── icons/star.png (1x)\n    │       ├── res-hdpi/\n    │       │   ├── cards/baby/card1.webp (1.5x)\n    │       │   ├── thumbs/baby/card1.webp (1.5x)\n    │       │   └── icons/star.png (1.5x)\n    │       ├── res-xhdpi/\n    │       │   ├── cards/baby/card1.webp (2x)\n    │       │   ├── thumbs/baby/card1.webp (2x)\n    │       │   └── icons/star.png (2x)\n    │       ├── res-xxhdpi/\n    │       │   ├── cards/baby/card1.webp (3x)\n    │       │   ├── thumbs/baby/card1.webp (3x)\n    │       │   └── icons/star.png (3x)\n    │       └── res-xxxhdpi/\n    │           ├── cards/baby/card1.webp (4x)\n    │           ├── thumbs/baby/card1.webp (4x)\n    │           └── icons/star.png (4x)\n    └── iphone/\n        └── images/\n            ├── cards/baby/\n            │   ├── card1.webp (1x)\n            │   ├── card1@2x.webp (2x)\n            │   └── card1@3x.webp (3x)\n            ├── thumbs/baby/\n            │   ├── card1.webp (1x)\n            │   ├── card1@2x.webp (2x)\n            │   └── card1@3x.webp (3x)\n            └── icons/\n                ├── star.png (1x)\n                ├── star@2x.png (2x)\n                └── star@3x.png (3x)\n```\n\n## Tips for alloy selective processing\n\n### During development:\n```bash\n# Test only what you're working on\nimgconvert -p alloy:comics -d    # Enable debug mode to see detailed processing\n```\n\n### Adding new asset categories:\n```bash\n# First, add your new configuration to .imgconverter.config.json\n# Then process only the new category\nimgconvert -p alloy:new-category\n```\n\n### Quality testing:\n```bash\n# Test different quality settings for specific configurations\nimgconvert -p alloy:comics -q 95          # Higher quality for main assets\nimgconvert -p alloy:thumbs-comics -q 60   # Lower quality for thumbnails\n```\n\n### CI/CD integration:\n```bash\n# Process only changed asset categories in your build pipeline\nif [[ \"$CHANGED_ASSETS\" == *\"comics\"* ]]; then\n  imgconvert -p alloy:comics\nfi\n```\n\n### Things to keep in mind\n\n- Use selective processing during development, run all configurations (`-p alloy`) for final builds\n- Combine with `-d` to see what's happening\n- CLI arguments override preset settings\n- Use consistent naming for your configurations\n- Test with debug mode first when setting up new configurations\n- Always verify configuration names exist before running automated scripts\n\n## Configuration File\n\nGlobal defaults and custom presets live in `.imgconverter.config.json`.\n\nGenerate a default config file with:\n\n```bash\nimgconvert config\n```\n\n### Configuration precedence\n\n1. CLI arguments (highest)\n2. Preset settings\n3. Global config (`.imgconverter.config.json`)\n4. Default values (lowest)\n\nThis applies to all parameters: `quality`, `format`, `width`, `height`, `output`, `replace-originals`, `background`, `fit`, `position`, and `crop`.\n\n### Parameters\n\n- **width** / **height**: Default dimensions for resizing.\n- **format**: Default output format.\n- **quality**: Default compression quality (1-100).\n- **fit**: Resize strategy (`cover`, `contain`, `fill`, `inside`, `outside`).\n- **position**: Crop/letterbox position (`center`, `top`, `bottom`, `left`, `right`, corners).\n- **crop**: Crop coordinates as `left,top,width,height`.\n- **canvas**: If true, extends canvas instead of scaling the image.\n- **replace-originals**: If true, overwrites the original files.\n- **source**: Default input folder (used when no path is given on the CLI).\n- **output**: Default output directory. If `null`, creates a `converted` folder next to the source.\n- **background**: Background color for transparency-to-opaque conversions (e.g., PNG to JPEG). PNG/WebP outputs keep transparency by default.\n- **presets**: Custom preset definitions. Each preset can override any of the above parameters.\n\n### Default configuration file\n\n#### Legacy alloy format:\n```json\n{\n  \"width\": null,\n  \"height\": null,\n  \"quality\": 85,\n  \"source\": null,\n  \"output\": null,\n  \"format\": null,\n  \"replace\": false,\n  \"background\": \"#ffffff\",\n  \"presets\": {\n    \"web\": { \"source\": null, \"format\": \"webp\", \"quality\": 80 },\n    \"print\": { \"source\": null, \"format\": \"tiff\", \"quality\": 100 },\n    \"thumbnail\": { \"source\": null, \"format\": \"png\", \"quality\": 60, \"width\": 150, \"height\": 150 },\n    \"alloy\": {\n      \"android\": {\n        \"source\": null,\n        \"output\": \"./app/assets/android/images\",\n        \"scales\": { \"res-mdpi\": 1, \"res-hdpi\": 1.5, \"res-xhdpi\": 2, \"res-xxhdpi\": 3, \"res-xxxhdpi\": 4 }\n      },\n      \"iphone\": {\n        \"source\": null,\n        \"output\": \"./app/assets/iphone/images\",\n        \"scales\": { \"1x\": 1, \"2x\": 2, \"3x\": 3 }\n      }\n    }\n  }\n}\n```\n\n#### Multi-configuration alloy format (recommended):\n```json\n{\n  \"width\": null,\n  \"height\": null,\n  \"quality\": 85,\n  \"fit\": \"contain\",\n  \"position\": \"center\",\n  \"crop\": null,\n  \"source\": null,\n  \"output\": null,\n  \"format\": null,\n  \"background\": null,\n  \"replace-originals\": false,\n\n  \"presets\": {\n    \"web\": { \"source\": null, \"output\": null, \"format\": \"webp\", \"quality\": 80 },\n    \"print\": { \"source\": null, \"output\": null, \"format\": \"tiff\", \"quality\": 100 },\n    \"thumbnail\": { \"source\": null, \"output\": null, \"format\": \"png\", \"quality\": 60, \"width\": 150, \"height\": 150 },\n    \"alloy\": {\n      \"cards\": {\n        \"android\": {\n          \"quality\": 90,\n          \"format\": \"webp\",\n          \"source\": \"originals\",\n          \"output\": \"cards/baby\"\n        },\n        \"iphone\": {\n          \"quality\": 90,\n          \"format\": \"webp\",\n          \"source\": \"originals\",\n          \"output\": \"cards/baby\"\n        }\n      },\n      \"thumbs\": {\n        \"android\": {\n          \"quality\": 80,\n          \"format\": \"webp\",\n          \"output\": \"thumbs/baby\",\n          \"source\": \"original-thumbs\"\n        },\n        \"iphone\": {\n          \"quality\": 80,\n          \"format\": \"webp\",\n          \"output\": \"thumbs/baby\",\n          \"source\": \"original-thumbs\"\n        }\n      }\n    }\n  }\n}\n```\n\n\u003e For the alloy preset, `output` should only be the relative subfolder (e.g., `\"thumbs/baby\"`). The base paths (`app/assets/android/images` and `app/assets/iphone/images`) are added automatically.\n\n**Precedence example with multi-configuration**\n\nGiven this configuration file:\n```json\n{\n  \"quality\": 75,\n  \"format\": \"jpeg\",\n\n  \"presets\": {\n    \"alloy\": {\n      \"cards\": {\n        \"android\": {\n          \"quality\": 90,\n          \"format\": \"webp\"\n        },\n        \"iphone\": {\n          \"quality\": 95,\n          \"format\": \"png\"\n        }\n      },\n      \"thumbs\": {\n        \"android\": {\n          \"quality\": 70,\n          \"format\": \"webp\"\n        },\n        \"iphone\": {\n          \"quality\": 75,\n          \"format\": \"webp\"\n        }\n      }\n    }\n  }\n}\n```\n\nResults:\n\n- `imgconvert -p alloy` →\n  - Cards: Android WebP at 90%, iPhone PNG at 95%\n  - Thumbs: Android WebP at 70%, iPhone WebP at 75%\n- `imgconvert -p alloy -q 80` → All platforms and configurations use JPEG at 80% (CLI overrides everything)\n- `imgconvert -p alloy -f jpeg` →\n  - Cards: Android JPEG at 90%, iPhone JPEG at 95%\n  - Thumbs: Android JPEG at 70%, iPhone JPEG at 75%\n- `imgconvert -p alloy -f webp -q 85` → All platforms and configurations use WebP at 85% (CLI overrides everything)\n\n## Debug mode\n\nUse `-d` or `--debug` to see detailed processing info.\n\n**Standard processing:**\n```\nProcessing complete! Summary:\n  - Processed files: 5\n  - Total original size: 0.87 MB\n  - Total new size: 0.25 MB\n  - Total savings: 71.11%\n  - Duration: 0.24 seconds\n```\n\n**Sample Debug Output (Multi-Configuration Alloy):**\n```\nProcessing configuration: cards\n  Processing android from: originals\n  Processing iphone from: originals\n\nProcessing configuration: thumbs\n  Processing android from: thumbs\n  Processing iphone from: thumbs\n\nProcessed files:\n - app/assets/android/images/res-mdpi/cards/baby/card1.webp (config: cards, platform: android, scale: res-mdpi)\n - app/assets/android/images/res-hdpi/cards/baby/card1.webp (config: cards, platform: android, scale: res-hdpi)\n - app/assets/iphone/images/cards/baby/card1.webp (config: cards, platform: iphone, scale: 1x)\n - app/assets/iphone/images/cards/baby/card1@2x.webp (config: cards, platform: iphone, scale: 2x)\n - app/assets/android/images/res-mdpi/thumbs/baby/thumb1.webp (config: thumbs, platform: android, scale: res-mdpi)\n ...\n\nProcessing complete! Summary:\n  - Processed files: 24\n  - Total original size: 2.45 MB\n  - Total new size: 0.89 MB\n  - Total savings: 63.67%\n  - Duration: 1.24 seconds\n```\n\n## Dependencies\n\n- **sharp** - Image processing (compression, conversion, resizing). Note: Sharp uses 'jpeg' internally, but imgconvert preserves '.jpg' extensions in filenames.\n- **minimist** - CLI argument parsing.\n- **chalk** - Colored terminal output.\n\n## Error handling\n\n- Missing source path shows an error and exits.\n- Unsupported formats fall back to the original format.\n- Non-image files are skipped with a log message.\n\n## Troubleshooting\n\n### Common issues\n\n**Q: Why did my `.jpg` file become `.jpeg` in older versions?**\nA: This was an issue in versions prior to 1.1.4. Update to the latest version where original extensions are preserved when no format conversion is specified.\n\n**Q: The CLI says \"format not supported\" for my file**\nA: Ensure your file has one of these extensions: `.jpeg`, `.jpg`, `.png`, `.webp`, `.avif`, `.tiff`, `.gif`\n\n**Q: Batch processing failed on some files**\nA: Check file permissions and ensure the output directory is writable. Use `--debug` flag for detailed error information.\n\n**Q: Output quality seems poor**\nA: Adjust quality with `-q` parameter (1-100). Default is 85. Use `-q 95` for higher quality.\n\n**Q: Permission denied error**\nA: Run with sudo on macOS/Linux: `sudo imgconvert ...` or check file/directory permissions.\n\n**Q: Sharp installation fails**\nA: Install build tools:\n```bash\n# On macOS\nxcode-select --install\n\n# On Ubuntu/Debian\nsudo apt-get install build-essential\n\n# On Windows\nnpm install -g windows-build-tools\n\n# Alternative: install node-gyp globally\nnpm install -g node-gyp\n```\n\n**Q: Out of memory on large batches**\nA: Process in smaller batches or increase Node.js memory:\n```bash\nnode --max-old-space-size=4096 $(which imgconvert) large-folder\n```\n\n**Q: Images appear blurry or pixelated**\nA: Ensure source images are high enough resolution. For Alloy preset, use 4x resolution source images for best results.\n\n**Q: Alloy preset not generating expected output structure**\nA: Verify your configuration file format and ensure output paths don't include leading/trailing slashes (use `\"thumbs/baby\"` not `\"/thumbs/baby/\"`). If files are not appearing where expected, check the output precedence: the `-o` flag takes priority, then the tool checks for `tiapp.xml` in the current directory (Titanium project detection), and finally falls back to the input file's directory.\n\n## Contributing\n\n### Development setup\n\n1. **Fork the repository**\n   ```bash\n   # On GitHub, click the \"Fork\" button\n   ```\n\n2. **Clone your fork**\n   ```bash\n   git clone https://github.com/yourusername/imgconvert-cli.git\n   cd imgconvert-cli\n   ```\n\n3. **Install dependencies**\n   ```bash\n   npm install\n   ```\n\n4. **Run tests**\n   ```bash\n   npm test\n   ```\n\n5. **Create your feature branch**\n   ```bash\n   git checkout -b feature/amazing-feature\n   ```\n\n6. **Make your changes and test**\n   ```bash\n   # Make your changes\n   npm test\n   npm run lint\n   ```\n\n7. **Commit your changes**\n   ```bash\n   git commit -m 'Add amazing feature'\n   ```\n\n8. **Push to your branch**\n   ```bash\n   git push origin feature/amazing-feature\n   ```\n\n9. **Open a Pull Request**\n   - Go to the original repository on GitHub\n   - Click \"New Pull Request\" or \"Compare \u0026 pull request\"\n   - **Select the correct branches**: `base: main` ← `compare: your-feature-branch`\n   - Provide a clear description of your changes\n   - **Reference issues**: Use \"Fixes #123\" or \"Closes #456\" if applicable\n   - **Add reviewers** if you know who should review your code\n   - Click \"Create Pull Request\"\n\n10. **After Creating the PR**\n    - Monitor for feedback and requested changes\n    - Make additional commits to the same branch if changes are needed\n    - **Keep your branch updated** with the main branch if needed:\n      ```bash\n      git checkout main\n      git pull upstream main\n      git checkout feature/amazing-feature\n      git merge main\n      ```\n\n\n### PR guidelines\n\n- Use a clear title (e.g., \"Add WebP optimization for mobile preset\")\n- Explain what you changed and why\n- Mark any breaking changes\n- Mention what tests you ran\n\n### PR description template:\n```\n## What does this PR do?\nBrief description of the changes\n\n## Why is this needed?\nExplain the problem this solves\n\n## How to test?\nSteps to verify the changes work\n\n## Checklist:\n- [ ] Tests pass\n- [ ] Documentation updated\n- [ ] No breaking changes (or clearly documented)\n```\n\n### Guidelines\n\n- Use clear commit messages\n- Reference issues in your PR\n- Follow existing code style (ESLint)\n- Add tests for new features\n- Update README if you change functionality\n\n## Roadmap\n\n- [ ] Progress bars for large batch operations\n- [ ] CLI wizard for preset configuration\n- [ ] Parallel processing for faster batch conversion\n- [ ] Plugin system for custom transformations\n- [ ] Docker support\n- [ ] Integration with build tools (Webpack, Vite)\n\nHave an idea? [Open an issue](https://github.com/macCesar/imgconvert-cli/issues).\n\n## License\n\nThis project is licensed under the MIT License.\n\n**Copyright (c) 2026 César Estrada**\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**Made with ❤️ by [César Estrada](https://github.com/macCesar)**\n\n[⭐ Star on GitHub](https://github.com/macCesar/imgconvert-cli) • [🐛 Report Bug](https://github.com/macCesar/imgconvert-cli/issues) • [💡 Request Feature](https://github.com/macCesar/imgconvert-cli/issues)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaccesar%2Fimgconvert-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaccesar%2Fimgconvert-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaccesar%2Fimgconvert-cli/lists"}