实现图形验证码:
private void generateVerificationCode() {GraphicsContext gc = codeCanvas.getGraphicsContext2D();int width = (int) codeCanvas.getWidth();int height = (int) codeCanvas.getHeight();// 清空画布gc.clearRect(0, 0, width, height);// 生成验证码文本(4位字母数字组合)verificationCode = generateRandomCode(4);// 绘制背景gc.setFill(Color.WHITE);gc.fillRect(0, 0, width, height);// 绘制干扰线drawInterferenceLines(gc, width, height);// 绘制验证码文本drawVerificationCode(gc, width, height);// 添加噪点drawNoise(gc, width, height);}private String generateRandomCode(int length) {String chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";StringBuilder sb = new StringBuilder();for (int i = 0; i < length; i++) {sb.append(chars.charAt(random.nextInt(chars.length())));}return sb.toString();}private void drawInterferenceLines(GraphicsContext gc, int width, int height) {gc.setStroke(Color.LIGHTGRAY);for (int i = 0; i < 5; i++) {gc.strokeLine(random.nextInt(width),random.nextInt(height),random.nextInt(width),random.nextInt(height));}}private void drawVerificationCode(GraphicsContext gc, int width, int height) {gc.setFont(Font.font(20));for (int i = 0; i < verificationCode.length(); i++) {// 设置随机颜色gc.setFill(Color.rgb(random.nextInt(150),random.nextInt(150),random.nextInt(150)));// 字符位置计算double x = 20 + i * 20;double y = height - 10;// 保存当前画布状态gc.save();// 添加旋转效果gc.translate(x, y);gc.rotate(random.nextDouble() * 30 - 15);// 绘制字符gc.fillText(String.valueOf(verificationCode.charAt(i)),-10,5);// 恢复画布状态gc.restore();}}private void drawNoise(GraphicsContext gc, int width, int height) {gc.setFill(Color.BLACK);for (int i = 0; i < 50; i++) {gc.fillRect(random.nextInt(width),random.nextInt(height),1, 1);}}
整体思路
- 清空画布:在生成新的验证码之前,先清空
Canvas
上原有的内容。 - 生成验证码文本:随机生成一个 4 位的字母数字组合作为验证码。
- 绘制背景:在画布上绘制白色背景。
- 添加干扰元素:为了防止验证码被机器自动识别,在画布上绘制干扰线和噪点。
- 绘制验证码文本:将生成的验证码文本以随机颜色和旋转效果绘制在画布上
代码详细解释
generateVerificationCode
方法
java
private void generateVerificationCode() {GraphicsContext gc = codeCanvas.getGraphicsContext2D();int width = (int) codeCanvas.getWidth();int height = (int) codeCanvas.getHeight();// 清空画布gc.clearRect(0, 0, width, height);// 生成验证码文本(4位字母数字组合)verificationCode = generateRandomCode(4);// 绘制背景gc.setFill(Color.WHITE);gc.fillRect(0, 0, width, height);// 绘制干扰线drawInterferenceLines(gc, width, height);// 绘制验证码文本drawVerificationCode(gc, width, height);// 添加噪点drawNoise(gc, width, height);
}
- 首先获取
Canvas
的GraphicsContext
对象,用于在画布上进行绘制操作。 - 接着获取画布的宽度和高度。
- 调用
clearRect
方法清空画布上的所有内容。 - 调用
generateRandomCode
方法生成一个 4 位的字母数字组合作为验证码。 - 设置填充颜色为白色,并使用
fillRect
方法绘制白色背景。 - 调用
drawInterferenceLines
方法绘制干扰线。 - 调用
drawVerificationCode
方法绘制验证码文本。 - 调用
drawNoise
方法添加噪点。
generateRandomCode
方法
java
private String generateRandomCode(int length) {String chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";StringBuilder sb = new StringBuilder();for (int i = 0; i < length; i++) {sb.append(chars.charAt(random.nextInt(chars.length())));}return sb.toString();
}
- 定义一个包含所有可能字符的字符串
chars
。 - 使用
StringBuilder
来构建验证码字符串。 - 通过
random.nextInt(chars.length())
随机选择一个字符,并添加到StringBuilder
中,重复length
次。 - 最后将
StringBuilder
转换为字符串并返回。
drawInterferenceLines
方法
java
private void drawInterferenceLines(GraphicsContext gc, int width, int height) {gc.setStroke(Color.LIGHTGRAY);for (int i = 0; i < 5; i++) {gc.strokeLine(random.nextInt(width),random.nextInt(height),random.nextInt(width),random.nextInt(height));}
}
- 设置笔触颜色为浅灰色。
- 使用
for
循环绘制 5 条干扰线,每条干扰线的起点和终点坐标都是随机生成的。
drawVerificationCode
方法
java
private void drawVerificationCode(GraphicsContext gc, int width, int height) {gc.setFont(Font.font(20));for (int i = 0; i < verificationCode.length(); i++) {// 设置随机颜色gc.setFill(Color.rgb(random.nextInt(150),random.nextInt(150),random.nextInt(150)));// 字符位置计算double x = 20 + i * 20;double y = height - 10;// 保存当前画布状态gc.save();// 添加旋转效果gc.translate(x, y);gc.rotate(random.nextDouble() * 30 - 15);// 绘制字符gc.fillText(String.valueOf(verificationCode.charAt(i)),-10,5);// 恢复画布状态gc.restore();}
}
- 设置字体大小为 20。
- 遍历验证码的每个字符,为每个字符设置随机颜色。
- 计算字符的绘制位置。
- 使用
gc.save()
保存当前画布状态。 - 通过
gc.translate
和gc.rotate
方法对画布进行平移和旋转操作,为字符添加随机旋转效果。 - 绘制字符。
- 使用
gc.restore()
恢复画布状态。
drawNoise
方法
java
private void drawNoise(GraphicsContext gc, int width, int height) {gc.setFill(Color.BLACK);for (int i = 0; i < 50; i++) {gc.fillRect(random.nextInt(width),random.nextInt(height),1, 1);}
}
- 设置填充颜色为黑色。
- 使用
for
循环绘制 50 个 1x1 像素的黑色矩形,作为噪点。
综上所述,这段代码通过一系列的绘制操作,在Canvas
上生成了一个包含干扰元素的验证码。