汪总电商平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

165 lines
4.5 KiB

/**
* Node点坐标合成脚本
* node index.js [验证码原图] [验证码输出地址] [验证码图旋转角度] [画布大小] [随机点数量] [随机线条数量] [随机大矩形数量]
*/
const {
createCanvas,
loadImage
} = require('canvas');
let fs = require('fs');
let initImg = process.argv[2];
if (!initImg) {
console.log("请传入需要生成验证码的原图")
process.exit();
}
try {
fs.accessSync(initImg, fs.constants.R_OK);
} catch (error) {
console.log("无法访问验证码原图")
process.exit();
}
let outImg = process.argv[3];
if (!outImg) {
console.log("请传入验证码的输出的地址")
process.exit();
}
let rotationAngle = Number(process.argv[4]);
if (rotationAngle < 0 || rotationAngle > 360) {
console.log("请传入正确的验证码旋转角度")
process.exit();
}
let canvasSize = process.argv[5] == undefined ? 480 : Number(process.argv[5]);
let randomPoint = process.argv[6] == undefined ? 200 : Number(process.argv[6]);
let randomLine = process.argv[7] == undefined ? 50 : Number(process.argv[7]);
let randomBlock = process.argv[8] == undefined ? 3 : Number(process.argv[8]);
drawCapImage(initImg, outImg, rotationAngle, canvasSize, randomPoint, randomLine, randomBlock).then(() => {
console.log("200")
}).catch(err => {
console.log("验证码图片生成失败")
process.exit();
})
/**
* 画线条
* rotate 围绕线条中心旋转
*/
function drawLine(ctx, x = 0, y = 0, width = 10, height = 1, bgColor = "#fff", rotate = 0) {
ctx.translate(x + width / 2, y + height / 2);
ctx.rotate((rotate) * Math.PI / 180);
ctx.fillStyle = bgColor;
ctx.fillRect(width / 2 * -1, height / 2 * -1, width, height);
ctx.rotate((360 - rotate) * Math.PI / 180);
ctx.translate((x + width / 2) * -1, (y + height / 2) * -1);
}
/**
* 生成从minNum到maxNum的随机数
*/
function randomNum(minNum, maxNum) {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1, 10);
break;
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
break;
default:
return 0;
break;
}
}
/**
* 验证码图片绘制
*/
async function drawCapImage(initImg, outImg, rotationAngle, canvasSize = 480, randomPoint = 200, randomLine = 50,
randomBlock = 3) {
return new Promise((yes, err) => {
try {
loadImage(initImg).then((image) => {
const canvas = createCanvas(canvasSize, canvasSize); //创建画板
const ctx = canvas.getContext('2d');
let option = { //图片写入参数
h: canvasSize, //高度
w: canvasSize //宽度
}
if (image.height > image.width) {
//高大于宽,竖屏照片
//设置高等于300,宽自动变化
let c = Math.ceil(canvasSize / image.width * 100) / 100;
option.h = Math.ceil(c * image.height);
option.w = canvasSize;
} else if (image.height < image.width) {
let c = Math.ceil(canvasSize / image.height * 100) / 100;
option.h = canvasSize;
option.w = Math.ceil(c * image.width);
}
ctx.translate((canvasSize / 2), (canvasSize / 2));
ctx.rotate(rotationAngle * Math.PI / 180);
ctx.arc(0, 0, (canvasSize / 2), 0, 2 * Math.PI); //限制在直径为150的圆内画图
ctx.clip();
ctx.translate(-(canvasSize / 2), -(canvasSize / 2));
ctx.drawImage(image, 0, 0, option.w, option.h);
ctx.translate((canvasSize / 2), (canvasSize / 2));
ctx.rotate((360 - rotationAngle) * Math.PI / 180);
ctx.translate(-(canvasSize / 2), -(canvasSize / 2));
/**
* 生成随机颜色点
*/
for (let index = 0; index < randomPoint; index++) {
drawLine(ctx,
randomNum(0, canvasSize),
randomNum(0, canvasSize),
randomNum(0, 4),
randomNum(0, 4),
"#" + (Array(6).join(0) + randomNum(0, 999999)).slice(-6),
randomNum(0, 360)
)
}
/**
* 随机生成线条
*/
for (let index = 0; index < randomLine; index++) {
drawLine(ctx,
randomNum(0, canvasSize),
randomNum(0, canvasSize),
randomNum(0, 200),
randomNum(0, 2),
"#" + (Array(6).join(0) + randomNum(0, 999999)).slice(-6),
randomNum(0, 360)
)
}
/**
* 随机生成大矩形
*/
for (let index = 0; index < randomBlock; index++) {
drawLine(ctx,
randomNum(0, canvasSize),
randomNum(0, canvasSize),
randomNum(0, 300),
randomNum(0, 40),
"#" + (Array(6).join(0) + randomNum(0, 999999)).slice(-6),
randomNum(0, 360)
)
}
canvas.createPNGStream().pipe(fs.createWriteStream(outImg))
yes()
})
} catch (error) {
err(error)
}
})
}