UNPKG

react-image-utilities

Version:

A React component library for image manipulation: cropping, compressing, resizing, format conversion, and effects

329 lines (258 loc) 8.95 kB
# React Image Utilities A powerful and flexible React component library for image manipulation, providing a comprehensive suite of tools for cropping, compressing, resizing, format conversion, and applying visual effects to images in your web applications. ## 🚀 Features - **📏 Image Cropping**: Interactive cropping with resizable crop area and aspect ratio control - **🗜️ Image Compression**: Smart compression with quality control and size limits - **↔️ Image Resizing**: Flexible resizing with multiple modes and aspect ratio preservation - **🔄 Format Conversion**: Convert between popular image formats (JPEG, PNG, WebP, GIF) - **✨ Visual Effects**: Apply professional-grade effects and filters - **📱 Responsive**: Works seamlessly across different screen sizes - **🔒 Type-Safe**: Written in TypeScript with full type definitions - **🎨 Customizable**: Extensive styling and configuration options ## 📦 Installation ```bash npm install react-image-utilities # or yarn add react-image-utilities # or pnpm add react-image-utilities ``` ## 💻 Usage ### Image Cropping ```tsx import { ImageCrop } from 'react-image-utilities'; function App() { const handleCropComplete = (croppedBlob: Blob) => { const url = URL.createObjectURL(croppedBlob); console.log('Cropped image URL:', url); }; return ( <ImageCrop image="/path/to/image.jpg" // Can be a File, Blob, or URL string width={300} height={200} aspectRatio={1.5} allowResize={true} showGrid={true} onProcessingComplete={handleCropComplete} onError={(error) => console.error('Crop error:', error)} /> ); } ``` ### Image Compression ```tsx import { ImageCompress } from 'react-image-utilities'; function App() { const handleCompressionComplete = (compressedBlob: Blob) => { console.log('Compressed size:', compressedBlob.size); }; return ( <ImageCompress image="/path/to/image.jpg" quality={75} maxSizeMB={1} showProgress={true} onCompressProgress={(progress) => console.log(`${progress}%`)} onProcessingComplete={handleCompressionComplete} onError={(error) => console.error('Compression error:', error)} /> ); } ``` ### Image Resizing ```tsx import { ImageResize } from 'react-image-utilities'; function App() { return ( <ImageResize image="/path/to/image.jpg" width={800} height={600} maintainAspectRatio={true} resizeMode="contain" onProcessingComplete={(resizedBlob) => { console.log('Resized image:', resizedBlob); }} /> ); } ``` ### Format Conversion ```tsx import { ImageFormat } from 'react-image-utilities'; function App() { return ( <ImageFormat image="/path/to/image.jpg" format="webp" quality={80} onProcessingComplete={(convertedBlob) => { console.log('Converted image:', convertedBlob); }} /> ); } ``` ### Visual Effects ```tsx import { ImageEffects } from 'react-image-utilities'; function App() { return ( <ImageEffects image="/path/to/image.jpg" effect="grayscale" intensity={75} onProcessingComplete={(processedBlob) => { console.log('Processed image:', processedBlob); }} /> ); } ``` ## 📚 API Reference ### Common Props All components share these base props: | Prop | Type | Description | |------|------|-------------| | `image` | `File \| Blob \| string` | The source image (File, Blob, or URL) | | `onProcessingComplete` | `(processedImage: Blob) => void` | Callback with processed image | | `onError` | `(error: Error) => void` | Error handling callback | | `className` | `string` | CSS class name | | `style` | `React.CSSProperties` | Inline styles | | `validateInput` | `boolean` | Enable input validation | | `onValidationError` | `(error: ValidationError) => void` | Validation error callback | ### ImageCrop | Prop | Type | Default | Description | |------|------|---------|-------------| | `width` | `number` | Required | Crop area width | | `height` | `number` | Required | Crop area height | | `aspectRatio` | `number` | `undefined` | Lock aspect ratio | | `allowResize` | `boolean` | `true` | Enable resize handles | | `showGrid` | `boolean` | `true` | Show grid overlay | | `gridColor` | `string` | `'rgba(255,255,255,0.8)'` | Grid line color | ### ImageCompress | Prop | Type | Default | Description | |------|------|---------|-------------| | `quality` | `number` | `80` | Compression quality (0-100) | | `maxSizeMB` | `number` | `undefined` | Max file size in MB | | `showProgress` | `boolean` | `true` | Show progress bar | | `onCompressProgress` | `(progress: number) => void` | `undefined` | Progress callback | ### ImageResize | Prop | Type | Default | Description | |------|------|---------|-------------| | `width` | `number` | Required | Target width | | `height` | `number` | Required | Target height | | `maintainAspectRatio` | `boolean` | `true` | Preserve aspect ratio | | `resizeMode` | `'contain' \| 'cover' \| 'stretch'` | `'contain'` | Resize behavior | ### ImageFormat | Prop | Type | Default | Description | |------|------|---------|-------------| | `format` | `'jpeg' \| 'png' \| 'webp' \| 'gif'` | Required | Target format | | `quality` | `number` | `80` | Output quality | ### ImageEffects | Prop | Type | Default | Description | |------|------|---------|-------------| | `effect` | `EffectType` | Required | Effect to apply | | `intensity` | `number` | `100` | Effect strength | | `blurRadius` | `number` | `undefined` | Blur amount | ## 🔧 Error Handling ### Error Types ```typescript type ImageProcessingErrorType = | 'INVALID_INPUT' | 'UNSUPPORTED_FORMAT' | 'COMPRESSION_FAILED' | 'RESIZE_FAILED' | 'FORMAT_CONVERSION_FAILED' | 'EFFECT_APPLICATION_FAILED'; ``` ### Example with Error Handling ```tsx import { ImageCompress, ValidationError } from 'react-image-utilities'; function App() { return ( <ImageCompress image={imageFile} quality={75} validateInput={true} onError={(error) => { if (error.type === 'COMPRESSION_FAILED') { console.error('Compression failed:', error.message); } }} onValidationError={(error) => { console.error('Validation failed:', error.message); }} retryOnError={true} maxRetries={3} /> ); } ``` ## 🌐 Browser Compatibility ### Feature Detection ```tsx import { checkBrowserSupport } from 'react-image-utilities'; const support = checkBrowserSupport(); if (!support.webp) { console.warn('WebP format not supported'); } ``` ### Minimum Browser Versions - Chrome: 79+ - Firefox: 73+ - Safari: 14+ - Edge: 79+ ## ⚡ Performance Considerations 1. **Image Size Limits** - Recommended max input image size: 20MB - For larger images, use compression first - Consider using Web Workers for heavy processing 2. **Memory Usage** - Images are processed in chunks when possible - Large images are automatically downscaled during preview - Resources are properly cleaned up after processing 3. **Processing Time** - Compression: ~100ms - 2s depending on size - Resizing: ~50ms - 1s depending on dimensions - Effects: ~50ms - 500ms depending on complexity ## 🔍 Troubleshooting ### Common Issues 1. **Image Not Loading** - Check if the image URL is accessible - Verify CORS settings for remote images - Ensure the image format is supported 2. **Processing Errors** - Check browser console for detailed error messages - Verify input image dimensions and format - Ensure sufficient memory is available 3. **Performance Issues** - Reduce input image size - Lower quality settings for faster processing - Use Web Workers for heavy operations ## 🤝 Contributing We welcome contributions! Please follow these steps: 1. Fork the repository 2. Create a feature branch 3. Commit your changes 4. Push to the branch 5. Open a Pull Request ### Development Setup ```bash # Clone the repository git clone https://github.com/yourusername/react-image-utilities.git # Install dependencies npm install # Start development server npm run dev # Run tests npm test ``` ## 📄 License MIT © [Your Name] --- ## 🙋 Support - Documentation: [https://github.com/yourusername/react-image-utilities](https://github.com/yourusername/react-image-utilities) - Issues: [https://github.com/yourusername/react-image-utilities/issues](https://github.com/yourusername/react-image-utilities/issues) - Discord: [Join our community](https://discord.gg/yourdiscord)