Java生成検証コード

4253 ワード

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Random;
import javax.imageio.ImageIO;

public class SimpleCaptcha {
	private static final String VALID_CHARS = "ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz0123456789"; // remove o,i,l

	private int width;//         。
	private int height;//         。
	private int fontSize; //     
	private int chars; //     

	private BufferedImage image;
	private Random random = new Random();

	public SimpleCaptcha() {
		this(100, 30, 26, 4);
	}

	public SimpleCaptcha(int width, int height, int fontSize, int chars) {
		this.width = width;
		this.height = height;
		this.fontSize = fontSize;
		this.chars = chars;
		this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	}

	public void createCode(File file) {
		try {
			FileOutputStream fos = new FileOutputStream(file);
			createCode(fos);
			fos.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public void createCode(OutputStream os) {
		Graphics2D g = image.createGraphics();

		drawBackground(g);
		drawRandomLines(g, 100);
		drawFrame(g);
		drawString();

		try {
			ImageIO.write(image, "JPEG", os);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private void drawBackground(Graphics2D g) {
		//        (      ,    )
		g.setColor(getRandomColor(180, 250));
		g.fillRect(0, 0, width, height);
	}

	/**
	 *      
	 * @param g	Graphics2D  ,      
	 * @param nums	      
	 */
	private void drawRandomLines(Graphics2D g, int nums) {
		g.setColor(getRandomColor(100, 200));
		int maxlength = 12;
		for (int i = 0; i < nums; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int xl = random.nextInt(maxlength);
			int yl = random.nextInt(maxlength);
			g.drawLine(x, y, x + xl, y + yl);
		}
	}

	private void drawFrame(Graphics2D g) {
		//   。
		g.setColor(Color.BLACK);
		g.drawRect(0, 0, width - 1, height - 1);
	}

	/**
	 *       
	 * @param fc	   
	 * @param bc	   
	 * @return	Color  , Color   RGB   。
	 */
	private Color getRandomColor(int fc, int bc) {//          
		if (fc > 255) fc = 255;
		if (bc > 255) bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

	private String getRandomString(int length) {
		char[] codes = new char[length];

		int size = VALID_CHARS.length();
		for (int i = 0; i < length; i++) {
			codes[i] = VALID_CHARS.charAt(random.nextInt(size));
		}
		return new String(codes);
	}

	private void drawString() {
		final String randomCode = getRandomString(chars);

		for (int i = 0; i < chars; i++) {
			String ch = randomCode.substring(i, i + 1);

			//    
			double scale = (random.nextInt(60) + 70D) / 100D;
			Font font = new Font("Consola", Font.BOLD, (int) (fontSize * scale));

			Graphics2D g = image.createGraphics();
			g.setFont(font);

			//    
			int w = g.getFontMetrics().charWidth(ch.charAt(0));
			int h = g.getFontMetrics().getAscent() - g.getFontMetrics().getDescent();

			int x1 = (width / chars) * i + (width / chars - w) / 2;
			int y1 = height - (height - h) / 2;

			int x2 = x1 + w / 2;
			int y2 = y1 - h / 2;

			g.rotate((random.nextInt(90) - 45) * Math.PI / 180, x2, y2);

			//     
			g.setColor(getRandomColor(1, 120));
			g.drawString(ch, x1, y1);
		}
	}

	public static void main(String[] args) {
		new SimpleCaptcha().createCode(new File("c:\\1.jpg"));
	}
}