draft v2
This commit is contained in:
parent
e1f2fdffbf
commit
e4926a3aa3
Binary file not shown.
|
@ -1,5 +1,12 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
td.description {
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 align="center">This is FreePtcha, a completely open source captcha.</h1>
|
<h1 align="center">This is FreePtcha, a completely open source captcha.</h1>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -27,14 +34,32 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
<h2>Example</h2>
|
<h2>Example</h2>
|
||||||
<p>
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
<a href="/captcha/v1/UwU">
|
<a href="/captcha/v1/UwU">
|
||||||
/captcha/v1/UwU<br/>
|
/captcha/v1/UwU<br/>
|
||||||
<img src="/captcha/v1/UwU" />
|
<img src="/captcha/v1/UwU" />
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/captcha/v2/UwU">
|
||||||
|
/captcha/v2/UwU<br/>
|
||||||
|
<img src="/captcha/v2/UwU" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="description">
|
||||||
A simple text stroked over a lot of times
|
A simple text stroked over a lot of times
|
||||||
</p>
|
</td>
|
||||||
|
<td class="description">
|
||||||
|
Text with a few random letters and circles in the background
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
|
53
routes.js
53
routes.js
|
@ -1,7 +1,10 @@
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
const canvas = require('canvas');
|
const canvas = require('canvas');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const randint = (min, max) => { return crypto.randomInt(max) + min };
|
const path = require('path');
|
||||||
|
const randint = (min, max) => { return crypto.randomInt(min, max) };
|
||||||
|
|
||||||
|
canvas.registerFont(path.join(__dirname, 'asset/lobster.ttf'), { family: 'Lobster' });
|
||||||
|
|
||||||
/** @param {import('fastify').FastifyRequest} req */
|
/** @param {import('fastify').FastifyRequest} req */
|
||||||
const getSettings = (req) => {
|
const getSettings = (req) => {
|
||||||
|
@ -89,5 +92,53 @@ module.exports = (fastify) => {
|
||||||
|
|
||||||
res.header('Content-Type', 'png');
|
res.header('Content-Type', 'png');
|
||||||
return draw.toBuffer();
|
return draw.toBuffer();
|
||||||
|
});
|
||||||
|
|
||||||
|
fastify.get('/captcha/v2/:text', async (req, res) => {
|
||||||
|
const text = req.params.text;
|
||||||
|
const settings = getSettings(req);
|
||||||
|
const size = get_size([settings.width, settings.height], settings.dpi, text.length, settings.padding);
|
||||||
|
size.height *= 0.5
|
||||||
|
|
||||||
|
const draw = canvas.createCanvas(size.width, size.height);
|
||||||
|
const ctx = draw.getContext('2d');
|
||||||
|
|
||||||
|
const arcs = randint(5, 32);
|
||||||
|
for (let i = 0; i != arcs; i++) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.strokeStyle = `rgba(${randint(0,255)},${randint(0,255)},${randint(0,255)},${randint(0,255)})`;
|
||||||
|
ctx.arc(randint(0, size.width), randint(0, size.height), randint(10, 25), 0, 360);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// let i = 0;
|
||||||
|
ctx.textDrawingMode = 'path';
|
||||||
|
|
||||||
|
const textStyles = ['#f00', '#2a4', '#00f', '#9a0', '#f0f'];
|
||||||
|
|
||||||
|
ctx.strokeStyle = textStyles[randint(0, textStyles.length)];
|
||||||
|
ctx.font = `${settings.dpi * 0.2}px sans-serif`;
|
||||||
|
|
||||||
|
textStyles.splice(textStyles.indexOf(ctx.strokeStyle), 1);
|
||||||
|
const gap = randint(50, 64);
|
||||||
|
for (const i in text) {
|
||||||
|
ctx.fillText(text[i], settings.padding + (i * randint(40,48)), randint(Math.floor(settings.padding + settings.dpi * 0.05), size.height - settings.padding + Math.floor(settings.dpi * 0.1)), 200);
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
|
||||||
|
const fauxletters = randint(20,40);
|
||||||
|
let alphabet = 'abcdefghijklmnopqrstuvwxyz';
|
||||||
|
alphabet += alphabet.toUpperCase();
|
||||||
|
alphabet += '0123456789';
|
||||||
|
for (let i = 0; i !== fauxletters; i++) {
|
||||||
|
ctx.strokeStyle = textStyles[randint(0,textStyles.length)] + '2';
|
||||||
|
ctx.font = `${settings.dpi * 0.2}px serif`
|
||||||
|
ctx.strokeText(alphabet[randint(0, alphabet.length)], randint(0, size.width), randint(0, size.height), 200);
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
|
||||||
|
res.header('Content-Type', 'image/png');
|
||||||
|
return draw.toBuffer();
|
||||||
})
|
})
|
||||||
}
|
}
|
Loading…
Reference in New Issue