Java 图形验证码

Like this:

/**
 * Create captcha
 *
 * @return CaptchaSNO object, not be null
 */
@NonNull
private CaptchaSNO createCaptcha() throws IOException {
    final int size = 100;
    final int length = 4;
    final char[] textRange = "23456789qazwsxedcrfvtgbyhnujmikpQAZWSXEDCRFVTGBYHNUJMKLP".toCharArray();
    final Color[] textColors = {Color.WHITE, Color.BLACK, Color.GREEN, Color.ORANGE, Color.YELLOW,
            Color.RED, Color.PINK, Color.BLUE};
    Random random = new Random(System.currentTimeMillis());
    // Get text
    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i < length; ++i) {
        stringBuilder.append(textRange[random.nextInt(textRange.length)]);
    }
    String text = stringBuilder.toString();
    // Create image
    int imageWidth = Math.round(length * 1.5F * size + size);
    int imageHeight = Math.round(size * 2.F);
    BufferedImage bufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics2D = bufferedImage.createGraphics();
    graphics2D.setColor(Color.DARK_GRAY);
    graphics2D.fillRect(0, 0, imageWidth, imageHeight);
    // Draw text
    int leftSpace = size / 2;
    int eachCharWidth = (imageWidth - size) / length;
    double angle2Radian = Math.PI / 180D;
    for (int i = 0; i < length; ++i) {
        graphics2D.setColor(textColors[random.nextInt(textColors.length)]);
        graphics2D.setFont(new Font(null, random.nextInt(2) > 0 ? Font.ITALIC : Font.PLAIN, size));
        int xPoint = leftSpace + i * eachCharWidth + random.nextInt(eachCharWidth - size);
        int yPoint = random.nextInt((imageHeight - size) / 2) + size;
        double rotateRadian = (random.nextInt(90) - 45) * angle2Radian;
        graphics2D.translate(xPoint, yPoint);
        graphics2D.rotate(rotateRadian);
        graphics2D.drawString(text.substring(i, i + 1), 0, 0);
        graphics2D.rotate(-rotateRadian);
        graphics2D.translate(-xPoint, -yPoint);
    }
    // Draw interference line
    int lineCount = Math.round(size * 0.3F);
    int maxLineWidth = Math.round(imageHeight * 0.040F);
    for (int i = 0; i < lineCount; ++i) {
        graphics2D.setColor(textColors[random.nextInt(textColors.length)]);
        graphics2D.setStroke(new BasicStroke(random.nextInt(maxLineWidth)));
        if (random.nextInt(4) > 1) {
            graphics2D.drawLine(random.nextInt(imageWidth), random.nextInt(imageHeight),
                    random.nextInt(imageWidth), random.nextInt(imageHeight));
        } else {
            graphics2D.draw(new QuadCurve2D.Double(random.nextInt(imageWidth), random.nextInt(imageHeight),
                    random.nextInt(imageWidth), random.nextInt(imageHeight),
                    random.nextInt(imageWidth), random.nextInt(imageHeight)));
        }
    }
    // Clear resource and convert to image
    graphics2D.dispose();
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    ImageIO.write(bufferedImage, "JPEG", byteArrayOutputStream);
    return new CaptchaSNO(text, byteArrayOutputStream.toByteArray());
}
原文地址:https://www.cnblogs.com/seliote/p/13276422.html