fix: 修改dockerfile,更新json文件

This commit is contained in:
huan 2024-08-12 10:55:25 +08:00
parent 0deaced829
commit 1aed3a8490
4 changed files with 75 additions and 72 deletions

View File

@ -1,20 +1,20 @@
# 使用官方Node.js 镜像作为基础镜像 # 使用官方Node.js镜像作为基础镜像
FROM node:18 FROM node:18-alpine
# 设置工作目录 # 设置工作目录
WORKDIR /app WORKDIR /app
# 复制 package.json package-lock.json(如果有)到工作目录 # 复制package.json和package-lock.json
COPY package*.json ./ COPY package*.json ./
# 安装依赖 # 安装依赖
RUN npm install RUN npm install
# 复制项目的源代码到工作目录 # 复制项目文件
COPY . . COPY . .
# 暴露服务端口 # 暴露服务端口
EXPOSE 3000 EXPOSE 3000
# 启动应用程序 # 启动服务
CMD ["npm", "start"] CMD ["node", "index.js"]

6
package-lock.json generated
View File

@ -8,9 +8,9 @@
"name": "image-generator-service", "name": "image-generator-service",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"canvas": "^2.9.0", "canvas": "^2.11.2",
"express": "^4.17.1", "express": "^4.19.2",
"qrcode": "^1.4.4" "qrcode": "^1.5.4"
} }
}, },
"node_modules/@mapbox/node-pre-gyp": { "node_modules/@mapbox/node-pre-gyp": {

View File

@ -3,12 +3,11 @@
"version": "1.0.0", "version": "1.0.0",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {
"start": "node src/index.js" "start": "node src/index.js"
}, },
"dependencies": { "dependencies": {
"canvas": "^2.9.0", "canvas": "^2.11.2",
"express": "^4.17.1", "express": "^4.19.2",
"qrcode": "^1.4.4" "qrcode": "^1.5.4"
} }
} }

View File

@ -1,21 +1,50 @@
const express = require('express'); const express = require('express');
const { createCanvas, loadImage } = require('canvas'); const { createCanvas, loadImage } = require('canvas');
const QRCode = require('qrcode'); const QRCode = require('qrcode');
const app = express(); const app = express();
app.use(express.json()); app.use(express.json());
async function generateImage(title, tags, qrData) { const getBackground = (ctx, x, y, cornerSize, width, height) => {
ctx.lineJoin = 'round';
ctx.lineWidth = 0.5;
ctx.moveTo(x + cornerSize, y);
// 右上角
ctx.arcTo(x + width, y, x + width, y + cornerSize, cornerSize);
// 右下角
ctx.lineTo(x + width, y + height - cornerSize);
ctx.arcTo(x + width, y + height, x + width - cornerSize, y + height, cornerSize);
// 左下角
ctx.lineTo(x + cornerSize, y + height);
ctx.arcTo(x, y + height, x, y + height - cornerSize, cornerSize);
// 左上角
ctx.lineTo(x, y + cornerSize);
ctx.arcTo(x, y, x + cornerSize, y, cornerSize);
ctx.closePath();
ctx.strokeStyle = '#f0f0f0';
ctx.fill();
ctx.stroke();
};
app.post('/generateImage', async (req, res) => {
const { title, tags, qrData } = req.body;
const canvas = createCanvas(378, 613); const canvas = createCanvas(378, 613);
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
// 主图
const mainPath = 'https://tachybase-1321007335.cos.ap-shanghai.myqcloud.com/f17e5a563df5dbd37a96913af892608f.png'; const mainPath = 'https://tachybase-1321007335.cos.ap-shanghai.myqcloud.com/f17e5a563df5dbd37a96913af892608f.png';
const mainImage = await loadImage(mainPath); const mainImage = await loadImage(mainPath);
ctx.drawImage(mainImage, 0, 0, canvas.width, canvas.height / 2 + 80); ctx.drawImage(mainImage, 0, 0, canvas.width, canvas.height / 2 + 80);
// 白色区域
ctx.fillStyle = '#ffffff'; ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 387, canvas.width, canvas.height); ctx.fillRect(0, 387, canvas.width, canvas.height);
// 标题
ctx.fillStyle = '#000000'; ctx.fillStyle = '#000000';
ctx.font = '600 22px Arial'; ctx.font = '600 22px Arial';
ctx.fillText(title, 20, canvas.height / 2 + 116); ctx.fillText(title, 20, canvas.height / 2 + 116);
// 标签背景
ctx.fillStyle = '#f0f0f0'; ctx.fillStyle = '#f0f0f0';
tags.forEach((tag, index) => { tags.forEach((tag, index) => {
const cornerSize = 12; const cornerSize = 12;
@ -27,83 +56,58 @@ async function generateImage(title, tags, qrData) {
const height = 26; const height = 26;
getBackground(ctx, x, y, cornerSize, width, height); getBackground(ctx, x, y, cornerSize, width, height);
}); });
['1'].forEach((value) => {
const codeWidth = 135; // 二维码背景
const codeHeight = 154; const codeWidth = 135;
const codeCornerSize = 12; const codeHeight = 154;
const codeX = 229; const codeCornerSize = 12;
const codeY = 440; const codeX = 229;
getBackground(ctx, codeX, codeY, codeCornerSize, codeWidth, codeHeight); const codeY = 440;
}); getBackground(ctx, codeX, codeY, codeCornerSize, codeWidth, codeHeight);
// 标签文字
ctx.font = '17px Arial'; ctx.font = '17px Arial';
ctx.fillStyle = '#5e5e5e'; ctx.fillStyle = '#5e5e5e';
tags.forEach((tag, index) => { tags.forEach((tag, index) => {
const textMeta = ctx.measureText(tag); const textMeta = ctx.measureText(tag);
const tagContent = { let tagContent = tag;
width: textMeta.width + 55,
tag,
};
const maxWidth = 173; const maxWidth = 173;
for (let i = 0; i <= 300; i++) {
if (tagContent.width < maxWidth) { if (textMeta.width > maxWidth) {
break; for (let i = tag.length; i > 0; i--) {
} else { tagContent = tag.slice(0, i) + '...';
const text = tagContent.tag.split('').slice(0, -1).join(''); if (ctx.measureText(tagContent).width < maxWidth) {
tagContent.tag = text;
const tagText = ctx.measureText(text + '...');
if (tagText.width < maxWidth) {
tagContent.tag = text + '...';
break; break;
} }
} }
} }
ctx.fillText(tagContent.tag, 48, 469 + index * 39);
ctx.fillText(tagContent, 48, 469 + index * 39);
}); });
// 标签图标
const icon = 'https://tachybase-1321007335.cos.ap-shanghai.myqcloud.com/c24fc8982d4a469e63f70538d96ead23.png'; const icon = 'https://tachybase-1321007335.cos.ap-shanghai.myqcloud.com/c24fc8982d4a469e63f70538d96ead23.png';
const iconImage = await loadImage(icon); const iconImage = await loadImage(icon);
tags.forEach((tag, index) => { tags.forEach((tag, index) => {
ctx.drawImage(iconImage, 26, 452 + index * 39, 17, 20); ctx.drawImage(iconImage, 26, 452 + index * 39, 17, 20);
}); });
// 二维码
const qrCodeCanvas = createCanvas(100, 100); const qrCodeCanvas = createCanvas(100, 100);
await QRCode.toCanvas(qrCodeCanvas, qrData); await QRCode.toCanvas(qrCodeCanvas, qrData);
const qrCodeImage = qrCodeCanvas; const qrCodeImage = qrCodeCanvas;
const qrCodeX = canvas.width - 139; ctx.drawImage(qrCodeImage, canvas.width - 139, 448, 116, 115);
const qrCodeY = 448;
ctx.drawImage(qrCodeImage, qrCodeX, qrCodeY, 116, 115); // 二维码文字
ctx.fillStyle = '#9d9d9d'; ctx.fillStyle = '#9d9d9d';
ctx.fillText('长按识别', 261, 585); ctx.fillText('长按识别', 261, 585);
return canvas.toDataURL('image/png'); // 返回DataURL
} const dataURL = canvas.toDataURL('image/png');
res.json({ dataURL });
app.post('/generate-image', async (req, res) => {
const { title, tags, qrData } = req.body;
try {
const dataURL = await generateImage(title, tags, qrData);
res.json({ dataURL });
} catch (error) {
res.status(500).send('Error generating image');
}
}); });
const getBackground = (ctx, x, y, cornerSize, width, height) => { const port = 3000;
ctx.lineJoin = 'round';
ctx.lineWidth = 0.5;
ctx.moveTo(x + cornerSize, y);
ctx.arcTo(x + width, y, x + width, y + cornerSize, cornerSize);
ctx.lineTo(x + width, y + height - cornerSize);
ctx.arcTo(x + width, y + height, x + width - cornerSize, y + height, cornerSize);
ctx.lineTo(x + cornerSize, y + height);
ctx.arcTo(x, y + height, x, y + height - cornerSize, cornerSize);
ctx.lineTo(x, y + cornerSize);
ctx.arcTo(x, y, x + cornerSize, y, cornerSize);
ctx.closePath();
ctx.strokeStyle = '#f0f0f0';
ctx.fill();
ctx.stroke();
};
const port = process.env.PORT || 3000;
app.listen(port, () => { app.listen(port, () => {
console.log(`Server is running on port ${port}`); console.log(`Server running on port ${port}`);
}); });