验证码图片生成

步骤1:创建画图工具类:RandomGraphic

package test;



import javax.imageio.ImageIO;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Random;





/**

* 生成随机数字或字母串,以图像方式显示,用于人工识别,使程序很难识别。

* 

* 减小系统被程序自动攻击的可能性。 *

* 生成的图形颜色由红、黑、蓝、紫4中随机组合而成,数字或字母垂直方向位置在 *

* 一定范围内也是随机的,减少被程序自动识别的几率。 *

* 由于数字的0,1,2易和字母的o,l,z混淆,使人眼难以识别,因此不生成数字和字母的混合串。 *

* 生成的串字母统一用小写,串的最大长度为16。 */ public class RandomGraphic { //字符的高度和宽度,单位为像素 private int wordHeight = 10; private int wordWidth = 15; //最大字符串个数 private static final int MAX_CHARCOUNT = 16; //垂直方向起始位置 private static final int initypos = 5; //要生成的字符个数,由工厂方法得到 private int charCount = 0; //颜色数组,绘制字串时随机选择一个 private static final Color[] CHAR_COLOR = {Color.RED, Color.BLUE, Color.MAGENTA, Color.blue}; //随机数生成器 private Random r = new Random(); /** * 生成图像的格式常量,PNG格式,生成为文件时扩展名为.png; *

* 输出到页面时需要设置MIME type 为image/png */ public static String GRAPHIC_PNG = "PNG"; //用工厂方法创建对象 protected RandomGraphic(int charCount) { this.charCount = charCount; } /** * 创建对象的工厂方法 * * @param charCount 要生成的字符个数,个数在1到16之间 * @return 返回RandomGraphic对象实例 * @throws Exception 参数charCount错误时抛出 */ public static RandomGraphic createInstance(int charCount) throws Exception { if (charCount < 1 || charCount > MAX_CHARCOUNT) { throw new Exception("Invalid parameter charCount,charCount should between in 1 and 16"); } return new RandomGraphic(charCount); } // 给定范围获得随机颜色 Color getRandColor(int fc, int bc) { Random random = new Random(); 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); } /*** 随机返回一种颜色,透明度0~255 0表示全透 * @return 随机返回一种颜色 * @param alpha 透明度0~255 0表示全透 */ private Color getColor(int alpha) { int R = (int) (Math.random() * 255); int G = (int) (Math.random() * 255); int B = (int) (Math.random() * 255); return new Color(R, G, B, alpha); } public String drawInputstr(int num, String graphicFormat, OutputStream out) throws IOException { String charValue = randAlphaStr(num); int width = (charCount + 2) * wordWidth; int height = wordHeight * 3; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); // 创建一个随机数生成器类。 Random random = new Random(); // 获取图形上下文 Graphics g = image.getGraphics(); // 设定背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width, height); //设定字体 g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 随机产生168条干扰线,使图象中的认证码不易被其它程序探测到 g.setColor(getRandColor(160, 200)); for (int i = 0; i < 168; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x, y, x + xl, y + yl); } // 绘制charValue,每个字符颜色随机 for (int i = 0; i < charCount; i++) { String c = charValue.substring(i, i + 1); Color color = CHAR_COLOR[randomInt(0, CHAR_COLOR.length)]; g.setColor(color); int xpos = (i + 1) * wordWidth; // 垂直方向上随机 int ypos = randomInt(initypos + wordHeight, initypos + wordHeight * 2); g.drawString(c, xpos, ypos); } g.dispose(); image.flush(); // 输出到流 ImageIO.write(image, graphicFormat, out); return charValue; } private String randAlphaStr(int num) { StringBuffer charValue = new StringBuffer(); String str = "0123456789"; Random random = new Random(); for (int i = 0; i < num; i++) { int number = random.nextInt(10); charValue.append(str.charAt(number)); } return charValue.toString(); } /** * 返回[from,to)之间的一个随机整数 * * @param from 起始值 * @param to 结束值 * @return [from, to)之间的一个随机整数 */ protected int randomInt(int from, int to) { return from + r.nextInt(to - from); } }

步骤2:测试代码:

ByteArrayOutputStream output = new ByteArrayOutputStream();

code = RandomGraphic.createInstance(4).drawInputstr(4, RandomGraphic.GRAPHIC_PNG, output);

code="";

System.out.println("----------------code:" + code);

byte[] captcha = output.toByteArray();

System.out.println("----------------:" + new String(captcha));

BASE64Encoder encoder = new BASE64Encoder();

String imagestr = encoder.encode(captcha);// 返回Base64编码过的字节数组字符串

System.out.println("----------------:" + imagestr);

步骤3:浏览器访问时加前缀:data:image/png;base64,

String url=data:"image/png;base64,"+imagestr;

 

你可能感兴趣的:(java,html,知识在于积累,加密解密)