import sharp from "sharp"; import {Logger} from "../logging/logger.js"; export class NameCardCreator { /** * Combines a template image with a user avatar and saves it * @param {string} templatePath - path to the template image * @param {string} avatarPath - path to the avatar * @returns {Promise} resulting image buffer */ static async getWelcomeCard(templatePath, avatarPath) { try{ const template = await this.loadTemplate(templatePath); const avatar = await this.handleAvatar(avatarPath); const result = await template .composite([{ input: avatar, top: 215, left: 200, }]) .toFile("namecard.png") console.log("✅ Welcome card created: welcome-card.png"); return result; } catch(err) { await Logger.error("Unable to create name card", err); } } /** * Loads the template file into a sharp instance * @param {string} path - file path * @returns {sharp.Sharp} sharp image object */ static async loadTemplate(path) { return sharp(path); } /** * Overlays an image (item) on top of a base image * @param {sharp.Sharp|string} base - sharp image or path * @param {{item:string, x:number, y:number}} overlay - overlay info * @returns {Promise} combined image */ static async mergeBitmaps(base, { item, x, y }) { return null; } static async handleAvatar(avatarPath) { const avatarSize = 670; const borderSize = 8; const radius = avatarSize / 2; const totalSize = avatarSize + borderSize * 2; const avatarBuffer = await sharp(avatarPath) .resize(avatarSize, avatarSize, { fit: "cover" }) .png() .toBuffer(); return await sharp({ create: { width: totalSize, height: totalSize, channels: 4, background: "#0000" } }) .composite([ { input: avatarBuffer, top: borderSize, left: borderSize } ]) .png() .toBuffer(); } }