59 lines
1.7 KiB
JavaScript
59 lines
1.7 KiB
JavaScript
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();
|
|
})
|
|
} |