revision:
1. Install Node.js
2. Create a Project :
mkdir watermark-project
cd watermark-project
npm init -y
"Jimp" is great for adding text watermarks with ease.
npm install jimp
const Jimp = require('jimp');
async function addTextWatermark(inputPath, outputPath, text, options) {
try {
const image = await Jimp.read(inputPath);
const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE);
// Customize text position and alignment
const textOptions = {
text: text,
alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER,
alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE,
};
// Add text to the image
image.print(
font,
10, // X offset (adjust for positioning)
10, // Y offset
textOptions,
image.getWidth(),
image.getHeight()
);
// Save the watermarked image
await image.write(outputPath);
console.log(`Watermark added successfully! Output: ${outputPath}`);
} catch (error) {
console.error('Error:', error);
}
}
// Usage Example
addTextWatermark(
'input.jpg', // Path to input image
'output-text.jpg', // Output path
'© My Copyright 2023', // Watermark text
{}
);
Position : adjust 10, 10 (X/Y offsets) or use Jimp.HORIZONTAL_ALIGN_CENTER for center alignment.
Font & Color : use Jimp.loadFont() for other fonts or create a custom font.
Opacity : adjust with image.bitmap.data (advanced).
"Sharp" is fast and ideal for overlaying images (e.g., logos).
npm install sharp
const sharp = require('sharp');
async function addImageWatermark(inputPath, watermarkPath, outputPath, position = 'southeast') {
try {
await sharp(inputPath)
.composite([{ input: watermarkPath, gravity: position }])
.toFile(outputPath);
console.log(`Watermark added successfully! Output: ${outputPath}`);
} catch (error) {
console.error('Error:', error);
}
}
// Usage Example
addImageWatermark(
'input.jpg', // Input image
'logo.png', // Watermark image (transparent PNG recommended)
'output-image.jpg', // Output path
'southeast' // Position: 'top-left', 'center', 'southeast', etc.
);
Position : Use gravity options like southeast (bottom-right), northwest (top-left), etc.
Resize Watermark : Add .resize({ width: 100 }) before .composite().
Opacity : Adjust with sharp() options (e.g., background: { r: 255, g: 255, b: 255, alpha: 0.5 }).
use Canvas for full control over text and image overlay:
npm install canvas
const { createCanvas, loadImage } = require('canvas');
const fs = require('fs');
async function addCombinedWatermark(inputPath, outputPath, text, watermarkPath) {
try {
const image = await loadImage(inputPath);
const canvas = createCanvas(image.width, image.height);
const ctx = canvas.getContext('2d');
// Draw the original image
ctx.drawImage(image, 0, 0);
// Add text watermark
ctx.font = '20px Arial';
ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(text, canvas.width / 2, canvas.height / 2);
// Add image watermark
const watermark = await loadImage(watermarkPath);
ctx.drawImage(
watermark,
canvas.width - watermark.width - 10, // X position
canvas.height - watermark.height - 10 // Y position
);
// Save the result
fs.writeFileSync(outputPath, canvas.toBuffer());
console.log(`Combined watermark added successfully! Output: ${outputPath}`);
} catch (error) {
console.error('Error:', error);
}
}
// Usage Example
addCombinedWatermark(
'input.jpg',
'output-combined.jpg',
'© 2023',
'logo.png'
);
use "Express" to handle image uploads via a web interface.
npm install express multer
const express = require('express');
const multer = require('multer');
const sharp = require('sharp');
const upload = multer({ dest: 'uploads/' });
const app = express();
const port = 3000;
app.post('/watermark', upload.single('image'), async (req, res) => {
try {
const outputPath = `output/${Date.now()}-watermarked.jpg`;
await sharp(req.file.path)
.composite([{ input: 'logo.png', gravity: 'southeast' }])
.toFile(outputPath);
res.download(outputPath);
} catch (error) {
res.status(500).send('Error adding watermark');
}
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Performance : use "Sharp" for large-scale or high-performance tasks; "Jimp" is simpler for text but slightly slower.
Transparency : ensure watermark images (e.g., logos) use an alpha channel (PNG format).
Error Handling : add try/catch blocks for robustness.
Customization : adjust font size, color, position, and opacity as needed.
Run your script with:
node text-watermark.js
node image-watermark.js
node combined-watermark.js
node server.js # For the web server