const { createCanvas, loadImage, registerFont } = require("canvas"); const exiftool = require("exiftool-vendored"); const fs = require("fs"); const path = require("path"); // Optional: Register a custom font if needed (must be a .ttf or .otf file) registerFont(path.join(__dirname, "fonts", "OpenSans-Regular.ttf"), { family: "Open Sans", }); function getDateInFilename(filename) { const datePattern = /\d{4}-\d{2}-\d{2}/; const match = filename.match(datePattern); return match ? match[0] : null; } function getTimeInFilename(filename) { const time = filename.split("_")[2]; return time ? time.split('.')[0] + ":" + time.split('.')[1] : null; } async function getImageDate(filename, imageInput) { try { const filePath = path.join(imageInput, filename); const hasDateInName = /\d{4}-\d{2}-\d{2}/.test(filename); let dateFromFilename = null; let timeFromFilename = null; if (hasDateInName) { dateFromFilename = getDateInFilename(filename); timeFromFilename = getTimeInFilename(filename); } if (dateFromFilename && timeFromFilename) { return `${dateFromFilename} ${timeFromFilename}`; } const tags = await exiftool.exiftool.read(filePath); if (tags?.DateTimeOriginal?.rawValue) { const [dateOnly, timeFull] = tags.DateTimeOriginal.rawValue.split(" "); const timeOnly = timeFull?.slice(0, 5); const [year, month, day] = dateOnly.split(":"); return `${year}-${month}-${day} ${timeOnly}`; } const stats = await fs.promises.stat(filePath); const mtime = stats.mtime; return `${mtime.getFullYear()}-${String(mtime.getMonth() + 1).padStart(2, "0")}-${String(mtime.getDate()).padStart(2, "0")} ${String(mtime.getHours()).padStart(2, "0")}:${String(mtime.getMinutes()).padStart(2, "0")}`; } catch (err) { console.error("Failed to read EXIF:", err); } } async function addWatermark(filename, buffer, watermarkText) { const image = await loadImage(buffer); const canvas = createCanvas(image.width, image.height); const ctx = canvas.getContext("2d"); // Draw the original image ctx.drawImage(image, 0, 0); // Watermark styles ctx.font = "32px 'Open Sans'"; ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; ctx.textAlign = "right"; ctx.textBaseline = "bottom"; // Draw the watermark ctx.fillText(watermarkText, image.width - 10, image.height - 10); return canvas.toBuffer("image/jpeg"); } async function watermarkAllImages(bufferMap, imageInput) { const outputMap = {}; for (const [filename, buffer] of Object.entries(bufferMap)) { const watermarkText = await getImageDate(filename, imageInput); const watermarkedBuffer = await addWatermark(filename, buffer, watermarkText); outputMap[filename] = watermarkedBuffer; } return outputMap; } module.exports = { watermarkAllImages, };