const sharp = require('sharp'); const canvas = require('canvas'); const crypto = require('crypto') /** @param {import('fastify').FastifyInstance} fastify */ module.exports = (fastify) => { fastify.get('/captcha/v1/:text', async (req, res) => { let pic = (await sharp({ create: { width: 150, height: 50, channels: 4, background: { r: 0, g: 0, b: 0, alpha: 0 } } })); const text = req.params.text; pic.composite([ { input: { text: { text: text, font: 'Arial', dpi: crypto.randomInt(150, 200), rgba: true } }, blend: 'over' } ]); const textpic = await pic .ensureAlpha() .toFormat('png', { compressionLevel: 6 }) .toBuffer(); const draw = canvas.createCanvas(150, 50); const ctx = draw.getContext('2d'); ctx.drawImage(await canvas.loadImage(textpic), 0, 0, 150, 50); const randint = (min, max) => { return crypto.randomInt(max) + min }; const strokes = randint(25, 50); for (let i = 0; i != strokes; i++) { ctx.strokeStyle = `rgba(0,0,0,${10})`; ctx.beginPath(); ctx.bezierCurveTo(randint(0, 150), randint(0, 50), randint(0, 150), randint(0, 50), randint(0, 150), randint(0, 50)); ctx.stroke(); } ctx.bezierCurveTo(20, 20, 20, 30, 70, 25); ctx.stroke(); res.header('Content-Type', 'png'); return draw.toBuffer(); }) }