template-project/backup/watermark-backup.js
2025-05-30 18:13:30 +08:00

66 lines
2.0 KiB
JavaScript

import sharp from "sharp";
import { exiftool } from "exiftool-vendored";
import fs from "fs";
import path from "path";
import { compressImages } from "./compress-backup.js";
// Folder paths
const inputFolder = "./compressedImage";
const outputFolder = "./watermarkedImages";
fs.mkdirSync(outputFolder, { recursive: true });
// Add watermark to all images
const addWatermark = async (inputPath, outputPath, watermarkText) => {
const { width, height } = await sharp(inputPath).metadata();
// Generate overlay text as an image
const svg = `
<svg width="${width}" height="${height}">
<style>
.label {
fill: red;
font-size: 30px;
font-family: Arial, sans-serif;
}
</style>
<text x="${width - 10}" y="${height - 10}" text-anchor="end" class="label">${watermarkText}</text>
</svg>
`;
return sharp(inputPath)
.composite([{ input: Buffer.from(svg), top: 0, left: 0 }])
.toFile(outputPath);
};
async function getImageDate(filePath) {
try {
const tags = await exiftool.read(filePath);
console.log("DateTimeOriginal: ", tags.FileModifyDate.rawValue); // Example: 2024-05-21T14:32:18.000Z
const dateOnly = tags.FileModifyDate.rawValue.split(" ")[0];
const timeOnly = tags.FileModifyDate.rawValue.split(" ")[1].slice(0, 5);
const [year, month, day] = dateOnly.split(":");
const formatted = `${year}-${month}-${day} ${timeOnly}`;
return formatted;
} catch (err) {
console.error("Failed to read EXIF:", err);
}
}
async function main() {
await compressImages();
// Process all images
const files = fs
.readdirSync(inputFolder)
.filter((f) => /\.(jpe?g|png)$/i.test(f));
for (const file of files) {
const inputPath = path.join(inputFolder, file);
const outputPath = path.join(outputFolder, file);
const watermarkText = await getImageDate(inputPath);
await addWatermark(inputPath, outputPath, watermarkText);
console.log(`Watermarked: ${file}`);
}
await exiftool.end(); // Important to close the process
}
main();