UNPKG

images-watermark

Version:

šŸš€ A powerful, fast, and user-friendly Node.js library for adding professional watermarks to images. Protect your content with text watermarks, logo overlays, or both! Built with Sharp for lightning-fast processing, featuring intelligent caching, flexible

305 lines (233 loc) • 10 kB
# šŸ–¼ļø Images Watermark [![npm version](https://badge.fury.io/js/images-watermark.svg)](https://badge.fury.io/js/images-watermark) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://img.shields.io/npm/dm/images-watermark.svg)](https://www.npmjs.com/package/images-watermark) > A powerful, fast, and user-friendly Node.js library for adding professional watermarks to images. Protect your content with text watermarks, logo overlays, or both! šŸ“– **[šŸ“š Full Documentation](https://images-watermark-documentation.vercel.app/)** - Complete guides, API reference, and examples ## ✨ Features - šŸŽÆ **Text Watermarks** - Add custom text with full styling control - šŸ–¼ļø **Image Watermarks** - Overlay logos or images as watermarks - šŸ”„ **Combined Watermarks** - Use both text and image watermarks simultaneously - ⚔ **High Performance** - Built with Sharp for lightning-fast processing - šŸŽØ **Customizable** - Control position, size, opacity, colors, and fonts - šŸ”’ **Security** - Referrer-based access control for protected content - šŸ’¾ **Intelligent Caching** - Automatic caching for improved performance - šŸ“± **Multiple Formats** - Support for PNG, JPEG, WebP, and more - šŸš€ **Batch Processing** - Process multiple images at once - šŸŽ›ļø **Flexible Positioning** - 9 different watermark positions - šŸ“š **Comprehensive Documentation** - Full JSDoc comments and examples ## šŸš€ Quick Start ### Installation ```bash npm install images-watermark ``` ### Basic Usage ```javascript const Watermark = require('images-watermark'); // Single image watermark const watermarkedImage = await Watermark.singleImageWatermark({ imagePath: './path/to/image.jpg', textWatermark: 'My Brand', allowedReferrers: ['https://mywebsite.com'], headers: { referer: 'https://mywebsite.com' } }); // Multiple images watermark const watermarkedImages = await Watermark.multiImageWatermark({ imagePaths: ['./image1.jpg', './image2.jpg'], watermarkPath: './logo.png', allowedReferrers: ['https://mywebsite.com'], headers: { referer: 'https://mywebsite.com' } }); ``` ## šŸ“– API Reference ### `Watermark.singleImageWatermark(options)` Add watermark to a single image. #### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `imagePath` | `string` | āœ… | - | Path to the source image | | `allowedReferrers` | `string[]` | āœ… | - | Array of allowed referrer domains | | `headers` | `object` | āœ… | - | Request headers for access control | | `watermarkPath` | `string` | āŒ | - | Path to watermark image (logo) | | `textWatermark` | `string` | āŒ | - | Text to use as watermark | | `appName` | `string` | āŒ | - | App name (alternative to textWatermark) | | `textColor` | `string` | āŒ | `'black'` | Text color | | `opacity` | `string` | āŒ | `'0.3'` | Text opacity (0.0-1.0) | | `fontWeight` | `string` | āŒ | `'800'` | Font weight | | `textLineSpacing` | `string` | āŒ | `'5'` | Line spacing multiplier | | `fontFamily` | `string` | āŒ | `'Inter, Arial, sans-serif'` | Font family | #### Returns - `Promise<Buffer>` - Watermarked image buffer - `Promise<string>` - Original image path (if access denied) ### `Watermark.multiImageWatermark(options)` Add watermark to multiple images in parallel. #### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `imagePaths` | `string[]` | āœ… | - | Array of image paths | | `allowedReferrers` | `string[]` | āœ… | - | Array of allowed referrer domains | | `headers` | `object` | āœ… | - | Request headers for access control | | `watermarkPath` | `string` | āŒ | - | Path to watermark image (logo) | | `textWatermark` | `string` | āŒ | - | Text to use as watermark | | `appName` | `string` | āŒ | - | App name (alternative to textWatermark) | | `textColor` | `string` | āŒ | `'black'` | Text color | | `opacity` | `string` | āŒ | `'0.3'` | Text opacity (0.0-1.0) | | `fontWeight` | `string` | āŒ | `'800'` | Font weight | | `textLineSpacing` | `string` | āŒ | `'5'` | Line spacing multiplier | | `fontFamily` | `string` | āŒ | `'Inter, Arial, sans-serif'` | Font family | #### Returns - `Promise<Buffer[]>` - Array of watermarked image buffers - `Promise<string[]>` - Array of original image paths (if access denied) ### Utility Methods #### `Watermark.clearCache()` Clear the internal watermark cache. #### `Watermark.getCacheStats()` Get cache statistics (hits, misses, keys, etc.). ## šŸŽÆ Examples ### 1. Text Watermark Only ```javascript const Watermark = require('images-watermark'); const watermarkedImage = await Watermark.singleImageWatermark({ imagePath: './photos/landscape.jpg', textWatermark: 'Ā© 2024 My Company', textColor: '#FF0000', opacity: '0.5', fontWeight: 'bold', allowedReferrers: ['https://mywebsite.com'], headers: { referer: 'https://mywebsite.com', 'user-agent': 'Mozilla/5.0...' } }); ``` ### 2. Image Watermark Only ```javascript const Watermark = require('images-watermark'); const watermarkedImage = await Watermark.singleImageWatermark({ imagePath: './photos/portrait.jpg', watermarkPath: './assets/logo.png', allowedReferrers: ['https://mywebsite.com'], headers: { referer: 'https://mywebsite.com', 'user-agent': 'Mozilla/5.0...' } }); ``` ### 3. Combined Text and Image Watermark ```javascript const Watermark = require('images-watermark'); const watermarkedImage = await Watermark.singleImageWatermark({ imagePath: './photos/product.jpg', watermarkPath: './assets/brand-logo.png', textWatermark: 'PROTECTED CONTENT', textColor: '#FFFFFF', opacity: '0.7', fontWeight: '900', fontFamily: 'Arial, sans-serif', allowedReferrers: ['https://mywebsite.com'], headers: { referer: 'https://mywebsite.com', 'user-agent': 'Mozilla/5.0...' } }); ``` ### 4. Batch Processing ```javascript const Watermark = require('images-watermark'); const imagePaths = [ './photos/image1.jpg', './photos/image2.jpg', './photos/image3.jpg' ]; const watermarkedImages = await Watermark.multiImageWatermark({ imagePaths, appName: 'My Brand', textColor: '#000000', opacity: '0.3', allowedReferrers: ['https://mywebsite.com'], headers: { referer: 'https://mywebsite.com', 'user-agent': 'Mozilla/5.0...' } }); ``` ### 5. Express.js Integration ```javascript const express = require('express'); const Watermark = require('images-watermark'); const path = require('path'); const app = express(); app.get('/watermark/:imageName', async (req, res) => { try { const imagePath = path.join(__dirname, 'images', req.params.imageName); const watermarkedImage = await Watermark.singleImageWatermark({ imagePath, textWatermark: 'Ā© 2024 My Website', allowedReferrers: ['https://mywebsite.com'], headers: req.headers }); res.setHeader('Content-Type', 'image/png'); res.send(watermarkedImage); } catch (error) { console.error('Watermark error:', error); res.status(500).send('Error processing image'); } }); app.listen(3000, () => { console.log('Server running on port 3000'); }); ``` ### 6. Cache Management ```javascript const Watermark = require('images-watermark'); // Get cache statistics const stats = Watermark.getCacheStats(); console.log('Cache hits:', stats.hits); console.log('Cache misses:', stats.misses); // Clear cache if needed Watermark.clearCache(); ``` ## šŸ”’ Security & Access Control The library uses referrer-based access control to protect your images: - **Allowed Referrers**: Specify domains that can access images without watermarks - **Headers Validation**: Uses request headers to determine access permissions - **Cookie Check**: Validates if user has proper authentication - **User-Agent Filtering**: Prevents automated access from certain user agents ### Access Control Logic ```javascript // Access is granted if: // 1. User has valid cookies // 2. User-Agent is not 'undici' (prevents automated access) // 3. Referrer is NOT in allowed list (forces watermark for external access) const isDirectAccess = headers['user-agent'] !== 'undici' && !isValidReferrer && headers.cookie; ``` ## šŸŽØ Customization Options ### Text Watermark Styling - **Color**: Any valid CSS color (`#FF0000`, `red`, `rgb(255,0,0)`) - **Opacity**: 0.0 to 1.0 (transparent to opaque) - **Font Weight**: CSS font-weight values (`normal`, `bold`, `100-900`) - **Font Family**: Any installed font family - **Line Spacing**: Multiplier for line spacing ### Watermark Positioning - **Text Watermarks**: Centered on the image - **Image Watermarks**: Southeast corner (bottom-right) - **Combined**: Text centered, image in southeast corner ## ⚔ Performance Features - **Intelligent Caching**: SVG watermarks are cached for 24 hours - **Parallel Processing**: Multiple images processed simultaneously - **Memory Efficient**: Uses Sharp for optimized image processing - **Async Operations**: Non-blocking image processing ## šŸ› ļø Requirements - Node.js >= 20.0.0 - Sharp (automatically installed) - Node-cache (automatically installed) ## šŸ“ License MIT License - see [LICENSE](LICENSE) file for details. ## šŸ¤ Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## šŸ”— Author Details [![portfolio](https://img.shields.io/badge/my_portfolio-000?style=for-the-badge&logo=ko-fi&logoColor=white)](https://tirth-gaudani.github.io/portfolio/) [![linkedin](https://img.shields.io/badge/linkedin-0A66C2?style=for-the-badge&logo=linkedin&logoColor=white)](https://in.linkedin.com/in/tirthgaudani) ⭐ **Star this repository if you find it helpful!**