121 lines
3.8 KiB
JavaScript
121 lines
3.8 KiB
JavaScript
const { createCanvas, loadImage, registerFont } = require("canvas");
|
||
const fs = require("fs");
|
||
const path = require("path");
|
||
|
||
registerFont(path.join(process.cwd(), `/public/font/PINGFANG MEDIUM.TTF`), {
|
||
family: "pf",
|
||
});
|
||
|
||
const mergeImage = async (name) => {
|
||
const WIDTH = 1080;
|
||
const HEIGHT = 1920;
|
||
const canvas = createCanvas(WIDTH, HEIGHT);
|
||
const context = canvas.getContext("2d");
|
||
const bg = await loadImage(
|
||
path.join(process.cwd(), "/public/merge/base_card1.jpg")
|
||
);
|
||
context.drawImage(bg, 0, 0, 1080, 1920);
|
||
context.font = "48px px";
|
||
context.fillStyle = "#282828";
|
||
context.textAlign = "center"; //文字水平居中
|
||
context.fillText(name, 566 / 2, 422);
|
||
|
||
context.font = `400 80px pf`;
|
||
context.textAlign = "center";
|
||
context.fillStyle = "red";
|
||
context.fillText(`龙马精神`, WIDTH / 2, 366 + 4);
|
||
// return canvas.toBuffer();
|
||
const out = fs.createWriteStream(__dirname + "/test2.png");
|
||
const stream = canvas.createPNGStream();
|
||
stream.pipe(out);
|
||
out.on("finish", () => console.log("The PNG file was created."));
|
||
};
|
||
|
||
// const avatarOrnament = async (avatarPath, ornamentPath, size = 512) => {
|
||
// // 1️⃣ 加载图片
|
||
// const avatarImg = await loadImage(avatarPath);
|
||
// const ornamentImg = await loadImage(ornamentPath);
|
||
|
||
// const width = avatarImg.width;
|
||
// const height = avatarImg.height;
|
||
|
||
// const canvas = createCanvas(width, height);
|
||
// const ctx = canvas.getContext("2d");
|
||
|
||
// // 3️⃣ 先画头像
|
||
// ctx.drawImage(avatarImg, 0, 0, width, height);
|
||
|
||
// // 4️⃣ 计算挂饰尺寸(取短边的 25%)
|
||
// const baseSize = Math.min(width, height);
|
||
// const ornamentSize = Math.floor(baseSize * 0.25);
|
||
|
||
// const ornamentRatio = ornamentImg.width / ornamentImg.height;
|
||
// const ornamentWidth =
|
||
// ornamentRatio >= 1 ? ornamentSize : ornamentSize * ornamentRatio;
|
||
|
||
// const ornamentHeight =
|
||
// ornamentRatio >= 1 ? ornamentSize / ornamentRatio : ornamentSize;
|
||
|
||
// // 5️⃣ 位置:右下角 + 内边距
|
||
// const padding = Math.floor(baseSize * 0.05);
|
||
|
||
// const x = width - ornamentWidth - padding;
|
||
// const y = height - ornamentHeight - padding;
|
||
|
||
// // 6️⃣ 阴影(非常关键:让合成“自然”)
|
||
// ctx.save();
|
||
// ctx.shadowColor = "rgba(0, 0, 0, 0.25)";
|
||
// ctx.shadowBlur = Math.floor(baseSize * 0.03);
|
||
// ctx.shadowOffsetX = Math.floor(baseSize * 0.01);
|
||
// ctx.shadowOffsetY = Math.floor(baseSize * 0.01);
|
||
|
||
// ctx.drawImage(ornamentImg, x, y, ornamentWidth, ornamentHeight);
|
||
// ctx.restore();
|
||
|
||
// // 6. 输出文件
|
||
// // const buffer = canvas.toBuffer("image/png");
|
||
// // fs.writeFileSync(outputPath, buffer);
|
||
// const out = fs.createWriteStream(__dirname + "/test3.png");
|
||
// const stream = canvas.createPNGStream();
|
||
// stream.pipe(out);
|
||
// out.on("finish", () => console.log("The PNG file was created."));
|
||
|
||
// return "success";
|
||
// };
|
||
|
||
const avatarOrnament = async (avatarPath, ornamentPath, size = 512) => {
|
||
// 1. 读取头像
|
||
const avatar = await loadImage(avatarPath);
|
||
|
||
// 2. Canvas 尺寸 = 头像尺寸(不裁剪)
|
||
const width = 500;
|
||
const height = 500;
|
||
|
||
const canvas = createCanvas(width, height);
|
||
const ctx = canvas.getContext("2d");
|
||
|
||
// 3. 绘制头像
|
||
ctx.drawImage(avatar, 0, 0, width, height);
|
||
|
||
// 4. 读取装饰外框(PNG,透明)
|
||
// const frame = await loadImage(ornamentPath);
|
||
const framePath = path.resolve(__dirname + "/66.png");
|
||
const frame = await loadImage(framePath);
|
||
// 5. 覆盖绘制外框
|
||
ctx.drawImage(frame, 0, 0, width, height);
|
||
// 6. 输出文件
|
||
// const buffer = canvas.toBuffer("image/png");
|
||
// fs.writeFileSync(outputPath, buffer);
|
||
const out = fs.createWriteStream(__dirname + "/test6.png");
|
||
const stream = canvas.createPNGStream();
|
||
stream.pipe(out);
|
||
out.on("finish", () => console.log("The PNG file was created."));
|
||
|
||
return "success";
|
||
};
|
||
|
||
module.exports = {
|
||
mergeImage,
|
||
avatarOrnament,
|
||
};
|