Files
the-jailor/wwwroot/core/welcome/nameCardCreator.js
2025-11-09 10:23:23 +01:00

78 lines
2.3 KiB
JavaScript

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<sharp.OutputInfo>} 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<sharp.Sharp>} 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();
}
}