JAVA图片验证码

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.Random;

import org.apache.commons.lang3.StringUtils;

/**
 * 图片验证码类
 */
public class Captcha {
    private int width = 100;
    private int height = 30;
    private Random random = new Random();
    private BufferedImage image;
    /** 验证码图片上显示的字符 */
    private String code;
    /** 波形的幅度倍数,越大扭曲的程序越高,一般为3 */
    private int twistLevel = 2;
    /** 干扰线数量 */
    private int noiseLineNumber = 3;
    /** 背景色 */
    private Color backgroundColor = Color.WHITE;
    /** 字体颜色 */
    // private Color foregroundColor = Color.BLACK;
    private Color[] colors = { Color.BLUE, Color.RED, Color.GREEN, Color.BLACK, Color.CYAN, Color.MAGENTA };

    private Color getRandomColor() {
        return colors[random.nextInt(colors.length)];
    }

    /**
     * @param width
     *            - 验证码图片宽度
     * @param height
     *            - 验证码图片高度
     * @param randomStr
     *            - 随机字符串
     * @return
     */
    public Captcha generate(int width, int height, String randomStr) {
        this.width = width;
        this.height = height;
        this.code = randomStr;
        if (StringUtils.isBlank(code)) {
            throw new RuntimeException("randomStr can not be empty.");
        }
        int xWidth = width / (code.length() + 2);
        int yIndex = height - 4;
        Graphics2D graphics = graphicsInit();
        for (int i = 0; i < code.length(); i++) {
            // graphics.setColor(foregroundColor);
            graphics.setColor(getRandomColor());
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.drawString(code.charAt(i) + "", (i + 1) * xWidth, yIndex);
        }
        setBuffImg(disturb());
        return this;
    }

    private Graphics2D graphicsInit() {
        Graphics2D graphics = buffImgInit().createGraphics();
        graphics.setColor(backgroundColor);
        graphics.fillRect(0, 0, width, height);
        graphics.setFont(new Font("Fixedsys", Font.ITALIC, height - 2));
        graphics.drawRect(0, 0, width - 1, height - 1);
        return graphics;
    }

    private BufferedImage buffImgInit() {
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        return image;
    }

    private BufferedImage disturb() {
        drawNoiseLine(image.createGraphics());
        return twistImage();
    }

    private void drawNoiseLine(Graphics2D graphics) {
        int x = 0;
        int y = 0;
        int xl = 0;
        int yl = 0;
        for (int i = 0; i < noiseLineNumber; i++) {
            x = random.nextInt(width * 2 / 3);
            y = random.nextInt(height * 2 / 3);
            xl = random.nextInt(width / 2);
            yl = random.nextInt(height / 2);
            // graphics.setColor(foregroundColor);
            graphics.setColor(getRandomColor());
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.drawLine(x, y, x + xl, y + yl);
        }
    }

    private BufferedImage twistImage() {
        double dMultValue = random.nextInt(9) + twistLevel;
        double dPhase = random.nextInt(6);// 波形的起始相位,取值区间(0-2*PI)
        BufferedImage destBi = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = destBi.createGraphics();
        graphics.setColor(backgroundColor);
        graphics.fillRect(0, 0, width, height);
        for (int i = 0; i < destBi.getWidth(); i++) {
            for (int j = 0; j < destBi.getHeight(); j++) {
                int nOldX = getXPosition4Twist(dPhase, dMultValue, destBi.getHeight(), i, j);
                int nOldY = j;
                if (nOldX >= 0 && nOldX < destBi.getWidth() && nOldY >= 0 && nOldY < destBi.getHeight()) {
                    destBi.setRGB(nOldX, nOldY, image.getRGB(i, j));
                }
            }
        }
        return destBi;
    }

    private int getXPosition4Twist(double dPhase, double dMultValue, int height, int xPosition, int yPosition) {
        double PI = Math.PI; // 此值越大,扭曲程度越大
        double dx = (double) (PI * yPosition) / height + dPhase;
        double dy = Math.sin(dx);
        return xPosition + (int) (dy * dMultValue);
    }

    public BufferedImage getImage() {
        return image;
    }

    public void setBuffImg(BufferedImage buffImg) {
        this.image = buffImg;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

}



使用示例:
String randomStr = RandomStringUtils.randomAlphabetic(4).toLowerCase();
request.getSession().setAttribute(KEY_CAPTCHA, randomStr);
BufferedImage bi = new Captcha().generate(200, 50, randomStr).getImage();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
encoder.encode(bi);
ImageIO.write(bi, "JPEG", response.getOutputStream());










猜你喜欢

转载自joeblow.iteye.com/blog/1767290