package com.walker.support.kaptcha; import com.walker.infrastructure.utils.StringUtils; import com.walker.web.CaptchaProvider; import com.walker.web.CaptchaResult; import com.walker.web.CaptchaType; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.util.Random; /** * 只有文字的验证码,数字或者字母。 * @author 时克英 * @date 2023-05-12 */ public class WordCaptchaProvider implements CaptchaProvider { private static final Random random = new Random(); private final int width = 80; //图片宽度 private final int height = 34; //图片高度 private final int stringNum = 4; //字符的数量 private final int lineSize = 40; //干扰线数量 @Override public CaptchaResult generateCaptcha(Object param) { CaptchaResult captchaResult = new CaptchaResult(); BufferedImage image = this.createImage(captchaResult); // captchaResult.setCode(code); captchaResult.setImage(image); return captchaResult; } @Override public boolean validateCaptcha(CaptchaResult data) { // 由业务子类继承并重写该方法完成校验,一般会把生成结果放入缓存,然后与给定的结果做对比。 return false; } @Override public CaptchaType getCaptchaType() { return CaptchaType.InputCode; } private BufferedImage createImage(CaptchaResult captchaResult){ Graphics Graphics = null; try { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); Graphics = image.getGraphics();// 获得BufferedImage对象的Graphics对象 Graphics.fillRect(0, 0, width, height);//填充矩形 Graphics.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//设置字体 Graphics.setColor(getRandColor(110, 133));//设置颜色 //绘制干扰线 for(int i = 0; i <= lineSize; i++) { drawLine(Graphics); } //绘制字符 String randomString = ""; for(int i = 1; i <= stringNum; i++) { randomString = drawString(Graphics, randomString, i); captchaResult.setCode(randomString); } return image; } catch (Exception ex){ ex.printStackTrace(); return null; } finally { if(Graphics != null){ Graphics.dispose();//释放绘图资源 } } } /** * 绘制字符串,返回绘制的字符串 * @param graphics 获得BufferedImage对象的Graphics对象 * @param randomString 随机字符串 * @param i 坐标倍数 * @since 2020-04-16 * @return string */ private String drawString(Graphics graphics, String randomString, int i) { Graphics2D g2d = (Graphics2D) graphics; g2d.setFont(getFont()); //设置字体 g2d.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat()));//设置颜色 String randChar = getRandomChar(random.nextInt(StringUtils.STRING_RANDOM_CHAR.length())); randomString += randChar; //组装 // int rot = getRandomNum(1,10); int rot = Integer.parseInt(StringUtils.generateRandomNumber(1)); // System.out.println(".......... rot = " + rot); g2d.translate(random.nextInt(3), random.nextInt(3)); g2d.rotate(rot * Math.PI / 180); g2d.drawString(randChar, 13*i, 20); g2d.rotate(-rot * Math.PI / 180); return randomString; } private void drawLine(Graphics graphics) { //起点(x,y) 偏移量x1、y1 int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(13); int yl = random.nextInt(15); graphics.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat())); graphics.drawLine(x, y, x + xl, y + yl); } private Font getFont() { return new Font("Fixedsys", Font.CENTER_BASELINE, 25); //名称、样式、磅值 } private String getRandomChar(int index) { //获取指定位置index的字符,并转换成字符串表示形式 return String.valueOf(StringUtils.STRING_RANDOM_CHAR.charAt(index)); } private Color getRandColor(int frontColor, int backColor) { if(frontColor > 255) frontColor = 255; if(backColor > 255) backColor = 255; int red = frontColor + random.nextInt(backColor - frontColor - 16); int green = frontColor + random.nextInt(backColor - frontColor -14); int blue = frontColor + random.nextInt(backColor - frontColor -18); return new Color(red, green, blue); } }