{"id":26110797,"url":"https://github.com/deepakness/optisharp","last_synced_at":"2025-12-25T03:06:47.856Z","repository":{"id":281327619,"uuid":"944943238","full_name":"deepakness/optisharp","owner":"deepakness","description":"High-performance Node.js batch image processor using sharp - resize, optimize, convert, and watermark images","archived":false,"fork":false,"pushed_at":"2025-08-24T10:00:56.000Z","size":6462,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-24T15:41:21.479Z","etag":null,"topics":["image","optimizer","sharp"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deepakness.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-08T09:38:34.000Z","updated_at":"2025-08-24T10:32:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"0700e0a1-0f64-4259-9de3-d6353e38b164","html_url":"https://github.com/deepakness/optisharp","commit_stats":null,"previous_names":["deepakness/optisharp"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/deepakness/optisharp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepakness%2Foptisharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepakness%2Foptisharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepakness%2Foptisharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepakness%2Foptisharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deepakness","download_url":"https://codeload.github.com/deepakness/optisharp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deepakness%2Foptisharp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28017733,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-25T02:00:05.988Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["image","optimizer","sharp"],"created_at":"2025-03-10T00:19:57.036Z","updated_at":"2025-12-25T03:06:47.851Z","avatar_url":"https://github.com/deepakness.png","language":"JavaScript","readme":"# Sharp Image Processor\n\n![License](https://img.shields.io/github/license/deepakness/optisharp)\n![Node Version](https://img.shields.io/badge/node-%3E%3D18.17.0-brightgreen.svg)\n\nA high-performance, EXIF-aware Node.js utility for batch processing images using the [Sharp](https://sharp.pixelplumbing.com/) library. It resizes, optimizes, and converts images (JPEG/PNG/WebP/AVIF/TIFF), handles transparency safely when converting to JPEG, and uses sensible fallbacks when the source format isn’t supported as an output.\n\n## 🎥 Demo\n\nhttps://github.com/user-attachments/assets/6c837d00-59bd-4ea4-96a7-88228351af24\n\n## 🚀 Features\n\n- **Batch Processing**: Process multiple images at once from an input directory\n- **Format Conversion**: Convert between JPEG, PNG, WebP, AVIF, TIFF formats\n- **Smart Resizing**: Resize images while maintaining aspect ratio\n- **Advanced Optimization**: Apply format-specific optimizations for maximum compression\n- **Quality Control**: Adjust output quality to balance file size and image quality\n- **Metadata Handling**: Option to strip metadata to further reduce file size\n- **Image Enhancement**: Apply sharpening to improve clarity\n- **Comprehensive Reports**: Detailed summary statistics on processing results\n- **User-Friendly Output**: Clear logging and formatted statistics\n- **Optional Watermarking**: Add text or image watermarks with customizable options\n\n## 📋 Requirements\n\n- **Node.js**: v18.17.0 or later\n- **NPM**: For installing dependencies\n\n## 🔧 Installation\n\n1. Clone this repository:\n   ```bash\n   git clone https://github.com/deepakness/optisharp.git\n   cd optisharp\n   ```\n\n2. Install the required dependencies:\n   ```bash\n   npm install\n   ```\n\n## 💻 Basic Usage\n\n1. Place all your images in the `/input` folder\n2. Run the script:\n   ```bash\n   npm start\n   ```\n   or\n   ```bash\n   node image-processor.js\n   ```\n3. Processed images will be saved in the `/output` folder\n4. View the summary report for optimization statistics\n\n## 📝 Configuration\n\nAll configuration options are located at the top of the `image-processor.js` file for easy customization:\n\n### Output Format\n\n```javascript\n// Output format: 'jpeg', 'png', 'webp', 'avif', 'tiff', or 'original' to keep the source format\nconst OUTPUT_FORMAT = 'jpeg';\n```\n\nIf `OUTPUT_FORMAT` is set to `original` but the source format is not supported as an output (for example, GIF or SVG), the tool will choose a safe fallback: `png` when the image has transparency, otherwise `jpeg`.\n\n### Quality Settings\n\n```javascript\n// Image quality (1-100) - Higher values mean better quality but larger file size\nconst QUALITY = 80;\n```\n\n### Resize Options\n\n```javascript\n// Resize options\nconst RESIZE = {\n  enabled: true,\n  width: 1200,  // Set to null to maintain aspect ratio based on height\n  height: null, // Set to null to maintain aspect ratio based on width\n  fit: 'inside' // 'cover', 'contain', 'fill', 'inside', 'outside'\n};\n```\n\n### Optimizations\n\n```javascript\n// Apply additional image optimizations\nconst OPTIMIZATIONS = {\n  sharpen: true,      // Apply mild sharpening to the image\n  removeMetadata: true // Remove EXIF and other metadata to reduce file size\n};\n```\n\n## 🖼️ Supported Image Formats\n\n| Format | Input | Output | Notes |\n|--------|-------|--------|-------|\n| JPEG   | ✅    | ✅     | Optimized with mozjpeg |\n| PNG    | ✅    | ✅     | High compression level |\n| WebP   | ✅    | ✅     | Excellent for web usage |\n| GIF    | ✅    | ❌     | Input supported, output not supported by Sharp |\n| AVIF   | ✅    | ✅     | Next-gen format with excellent compression |\n| TIFF   | ✅    | ✅     | |\n| SVG    | ✅    | ❌     | Can be used as input only |\n\n## 📊 Fit Options Explained\n\n| Fit Option | Description |\n|------------|-------------|\n| `cover`    | Preserves aspect ratio and ensures the image covers both provided dimensions by cropping/clipping to fit |\n| `contain`  | Preserves aspect ratio and ensures the image fits within the provided dimensions |\n| `fill`     | Ignores the aspect ratio and stretches to the provided dimensions |\n| `inside`   | Preserves aspect ratio and resizes to the maximum dimensions that fit within the provided dimensions |\n| `outside`  | Preserves aspect ratio and resizes to the minimum dimensions that cover the provided dimensions |\n\n## 📈 Example Output\n\n```\nFound 3 files in the input directory.\n==================================================\nProcessing: sample.jpg\n  Original: 1920x1080, jpeg\n  Processed: 1200x675, jpeg\n  Size: 2.34 MB → 156.78 KB (93.45% reduction)\n  Done!\n--------------------------------------------------\nProcessing: photo.png\n  Original: 800x600, png\n  Processed: 800x600, jpeg\n  Size: 1.12 MB → 89.45 KB (92.01% reduction)\n  Done!\n--------------------------------------------------\nProcessing: icon.svg\n  Original: 512x512, svg\n  Processed: 512x512, jpeg\n  Size: 24.56 KB → 18.34 KB (25.33% reduction)\n  Done!\n--------------------------------------------------\n==================================================\n                 SUMMARY REPORT                   \n==================================================\nTotal files processed: 3 files\nSuccessfully processed: 3 files\nErrors: 0 files\nSkipped: 0 files\n--------------------------------------------------\nOutput format breakdown:\n  JPEG: 3 files (100.0%)\n--------------------------------------------------\nSize statistics:\n  Total original size: 3.48 MB\n  Total processed size: 264.57 KB\n  Total space saved: 3.22 MB (92.57% reduction)\n--------------------------------------------------\nTime statistics:\n  Total processing time: 1.25 seconds\n  Average time per image: 0.42 seconds\n==================================================\n✨ Image processing completed successfully! ✨\n```\n\n## 📈 How It Works\n\n1. The script scans the `/input` directory for image files\n2. For each valid image:\n   - Retrieves original metadata and dimensions\n   - Applies EXIF orientation automatically\n   - Applies configured resizing (if enabled)\n   - Applies sharpening (if enabled)\n   - Removes metadata (if enabled)\n   - Converts to the target format with quality settings\n   - Applies format-specific optimizations\n   - Saves to the `/output` directory\n 3. Generates a comprehensive summary report\n\nNote: When converting images with transparency to JPEG, transparent regions are flattened to white to ensure predictable results.\n\n## 🧩 Advanced Usage\n\n### Processing Specific Image Types\n\nTo process only specific types of images, you can modify the file pattern check in the script:\n\n```javascript\nconst isImageFile = /\\.(jpe?g|png|webp)$/i.test(fileInfo.ext); // Only process JPG, PNG and WebP\n```\n\n### Adding Custom Processing Steps\n\nSharp offers many image processing capabilities not included in this script. You can add custom operations by modifying the pipeline:\n\n```javascript\n// Example: Add a grayscale effect\npipeline = pipeline.grayscale();\n\n// Example: Add a blur effect\npipeline = pipeline.blur(3);\n\n// Example: Rotate an image\npipeline = pipeline.rotate(90);\n```\n\n## 💦 Watermarking (Optional Feature)\n\noptisharp includes an optional watermarking feature that allows you to add either text or image watermarks to your processed images. This feature is **disabled by default** but can be enabled by modifying the configuration.\n\n### Watermark Configuration\n\n```javascript\n// Watermark options\nconst WATERMARK = {\n  enabled: false,               // Enable/disable watermarking (disabled by default)\n  type: 'image',                // 'image' or 'text'\n  \n  // Image watermark options (used when type is 'image')\n  imagePath: './assets/watermark.png', // Path to watermark image\n  \n  // Text watermark options (used when type is 'text')\n  text: 'Copyright © 2024',     // Text to use as watermark\n  font: 'Arial',                // Font family\n  fontSize: 24,                 // Font size\n  fontColor: '#ffffff',         // Font color (accepts hex codes, color names, etc.)\n  \n  // Common watermark options\n  position: 'bottomRight',      // Position: topLeft, topRight, bottomLeft, bottomRight, center\n  opacity: 0.6,                 // Opacity (0-1)\n  margin: 20,                   // Margin from edges in pixels\n  size: 0.2,                    // Size ratio (percent of main image width) - for image watermarks only\n  angle: 0                      // Rotation angle in degrees - for text watermarks only\n};\n```\n\n### Using Image Watermarks\n\nTo use an image watermark:\n\n1. Create or select an image to use as your watermark (PNG with transparency works best)\n2. Place the watermark image in the `/assets` directory (create this directory if it doesn't exist)\n3. Update the `WATERMARK.imagePath` to point to your watermark file\n4. Set `WATERMARK.enabled` to `true` and `WATERMARK.type` to `'image'`\n5. Adjust other options as needed:\n   - `size`: Controls how large the watermark is relative to the image (0.2 = 20% of image width)\n   - `opacity`: Controls transparency (0-1 where 1 is fully opaque)\n   - `position`: Controls where the watermark appears on the image\n   - `margin`: Controls how far from the edge the watermark appears\n\n### Using Text Watermarks\n\nTo use a text watermark:\n\n1. Set `WATERMARK.enabled` to `true` and `WATERMARK.type` to `'text'`\n2. Configure the text options:\n   - `text`: The text to display (e.g., copyright notice, website URL, etc.)\n   - `font`: Font family to use (system fonts available)\n   - `fontSize`: Size of the text (or leave unset to auto-size based on image dimensions)\n   - `fontColor`: Color of the text (accepts hex codes like '#FF0000' for red)\n   - `angle`: Rotation angle in degrees (0-360)\n3. Adjust position, opacity, and margin as needed\n\n### Watermark Positioning Options\n\n| Position | Description |\n|----------|-------------|\n| `topLeft` | Places the watermark at the top-left corner |\n| `top` | Places the watermark at the top-center |\n| `topRight` | Places the watermark at the top-right corner |\n| `left` | Places the watermark at the middle-left |\n| `center` | Places the watermark at the center of the image |\n| `right` | Places the watermark at the middle-right |\n| `bottomLeft` | Places the watermark at the bottom-left corner |\n| `bottom` | Places the watermark at the bottom-center |\n| `bottomRight` | Places the watermark at the bottom-right corner |\n\n### Example with Watermarking\n\nWhen watermarking is enabled, the console output will show additional information:\n\n```\nProcessing: sample.jpg\n  Original: 1920x1080, jpeg\n  Applied image watermark (bottomRight, 60% opacity)\n  Processed: 1200x675, jpeg\n  Size: 2.34 MB → 156.78 KB (93.45% reduction)\n  Done!\n```\n\nAnd the summary will include watermarking statistics:\n\n```\nTotal files processed: 3 files\nSuccessfully processed: 3 files\nErrors: 0 files\nSkipped: 0 files\nWatermarked: 3 files\n```\n\n## 🛠️ Troubleshooting\n\n### Common Issues\n\n- **Error: Input buffer contains unsupported image format**: The input file is not a valid image or is corrupted.\n- **Error: Installation issues**: Try reinstalling with `npm install sharp --unsafe-perm=true`.\n\n### Performance Tips\n\n- Processing many large images can consume significant memory. Consider processing in smaller batches.\n- If speed is critical, disable sharpening or reduce the quality settings.\n\n## 🤝 Contributing\n\nContributions are welcome! Please check out our [Contributing Guide](CONTRIBUTING.md) for details.\n\n## 📜 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 📣 Acknowledgements\n\n- [Sharp](https://sharp.pixelplumbing.com/) - The high-performance Node.js image processing library that powers this tool\n- [Node.js](https://nodejs.org/) - The JavaScript runtime\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeepakness%2Foptisharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeepakness%2Foptisharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeepakness%2Foptisharp/lists"}