From 1aed3a849035337ca9e2d297c0047697ea7662ef Mon Sep 17 00:00:00 2001 From: huan <1486343814@qq.com> Date: Mon, 12 Aug 2024 10:55:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9dockerfile=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0json=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 12 ++--- package-lock.json | 6 +-- package.json | 11 ++--- src/index.js | 118 ++++++++++++++++++++++++---------------------- 4 files changed, 75 insertions(+), 72 deletions(-) diff --git a/Dockerfile b/Dockerfile index b2792a5..d59d755 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,20 @@ -# 使用官方的 Node.js 镜像作为基础镜像 -FROM node:18 +# 使用官方Node.js镜像作为基础镜像 +FROM node:18-alpine # 设置工作目录 WORKDIR /app -# 复制 package.json 和 package-lock.json(如果有)到工作目录 +# 复制package.json和package-lock.json COPY package*.json ./ # 安装依赖 RUN npm install -# 复制项目的源代码到工作目录 +# 复制项目文件 COPY . . # 暴露服务端口 EXPOSE 3000 -# 启动应用程序 -CMD ["npm", "start"] +# 启动服务 +CMD ["node", "index.js"] diff --git a/package-lock.json b/package-lock.json index 9935dc0..22dff73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,9 @@ "name": "image-generator-service", "version": "1.0.0", "dependencies": { - "canvas": "^2.9.0", - "express": "^4.17.1", - "qrcode": "^1.4.4" + "canvas": "^2.11.2", + "express": "^4.19.2", + "qrcode": "^1.5.4" } }, "node_modules/@mapbox/node-pre-gyp": { diff --git a/package.json b/package.json index 0c993a7..ed7d7ad 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,11 @@ "version": "1.0.0", "main": "src/index.js", "scripts": { - "start": "node src/index.js" + "start": "node src/index.js" }, "dependencies": { - "canvas": "^2.9.0", - "express": "^4.17.1", - "qrcode": "^1.4.4" + "canvas": "^2.11.2", + "express": "^4.19.2", + "qrcode": "^1.5.4" } - } - \ No newline at end of file +} diff --git a/src/index.js b/src/index.js index 4db0ff0..1ddf5ba 100644 --- a/src/index.js +++ b/src/index.js @@ -1,21 +1,50 @@ const express = require('express'); const { createCanvas, loadImage } = require('canvas'); const QRCode = require('qrcode'); - const app = express(); 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 ctx = canvas.getContext('2d'); + + // 主图 const mainPath = 'https://tachybase-1321007335.cos.ap-shanghai.myqcloud.com/f17e5a563df5dbd37a96913af892608f.png'; const mainImage = await loadImage(mainPath); ctx.drawImage(mainImage, 0, 0, canvas.width, canvas.height / 2 + 80); + + // 白色区域 ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 387, canvas.width, canvas.height); + + // 标题 ctx.fillStyle = '#000000'; ctx.font = '600 22px Arial'; ctx.fillText(title, 20, canvas.height / 2 + 116); + + // 标签背景 ctx.fillStyle = '#f0f0f0'; tags.forEach((tag, index) => { const cornerSize = 12; @@ -27,83 +56,58 @@ async function generateImage(title, tags, qrData) { const height = 26; getBackground(ctx, x, y, cornerSize, width, height); }); - ['1'].forEach((value) => { - const codeWidth = 135; - const codeHeight = 154; - const codeCornerSize = 12; - const codeX = 229; - const codeY = 440; - getBackground(ctx, codeX, codeY, codeCornerSize, codeWidth, codeHeight); - }); + + // 二维码背景 + const codeWidth = 135; + const codeHeight = 154; + const codeCornerSize = 12; + const codeX = 229; + const codeY = 440; + getBackground(ctx, codeX, codeY, codeCornerSize, codeWidth, codeHeight); + + // 标签文字 ctx.font = '17px Arial'; ctx.fillStyle = '#5e5e5e'; tags.forEach((tag, index) => { const textMeta = ctx.measureText(tag); - const tagContent = { - width: textMeta.width + 55, - tag, - }; + let tagContent = tag; const maxWidth = 173; - for (let i = 0; i <= 300; i++) { - if (tagContent.width < maxWidth) { - break; - } else { - const text = tagContent.tag.split('').slice(0, -1).join(''); - tagContent.tag = text; - const tagText = ctx.measureText(text + '...'); - if (tagText.width < maxWidth) { - tagContent.tag = text + '...'; + + if (textMeta.width > maxWidth) { + for (let i = tag.length; i > 0; i--) { + tagContent = tag.slice(0, i) + '...'; + if (ctx.measureText(tagContent).width < maxWidth) { 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 iconImage = await loadImage(icon); tags.forEach((tag, index) => { ctx.drawImage(iconImage, 26, 452 + index * 39, 17, 20); }); + + // 二维码 const qrCodeCanvas = createCanvas(100, 100); await QRCode.toCanvas(qrCodeCanvas, qrData); const qrCodeImage = qrCodeCanvas; - const qrCodeX = canvas.width - 139; - const qrCodeY = 448; - ctx.drawImage(qrCodeImage, qrCodeX, qrCodeY, 116, 115); + ctx.drawImage(qrCodeImage, canvas.width - 139, 448, 116, 115); + + // 二维码文字 ctx.fillStyle = '#9d9d9d'; ctx.fillText('长按识别', 261, 585); - return canvas.toDataURL('image/png'); -} - -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'); - } + // 返回DataURL + const dataURL = canvas.toDataURL('image/png'); + res.json({ dataURL }); }); -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(); -}; - -const port = process.env.PORT || 3000; +const port = 3000; app.listen(port, () => { - console.log(`Server is running on port ${port}`); + console.log(`Server running on port ${port}`); });