- package com.fullgoal.ip.config;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.image.BufferedImage;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.Random;
- import javax.imageio.ImageIO;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- /* 验证码图片生成步骤
- 创建BufferedImage对象。
- 获取BufferedImage的画笔,即调用getGraphics()方法获取Graphics对象。
- 调用Graphics对象的setColor()方法和fillRect()方法设置图片背景颜色。
- 调用Graphics对象的setColor()方法和drawLine()方法设置图片干扰线。
- 调用BufferedImaged对象的setRGB()方法设置图片的噪点。
- 调用Graphics对象的setColor()方法、setFont()方法和drawString()方法设置图片验证码。
- 因为验证码的图片的宽度和高度要根据网站的风格来确定的,所以字体的大小需要根据图片的宽度和高度来确定,用到了小小的技巧。
- */
- public class Verification {
- private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
- /**
- * 生成一个宽为width, 高为height, 验证码为vcode的图片
- * @param width 图片的宽
- * @param height 图片的高
- * @param vcode 验证码字符串
- * @return 返回图片验证码
- */
- public static BufferedImage getImage(int width, int height, String vvcode){
- return getImage(width, height, vvcode, 20);
- }
- /**
- * 生成一个宽为width, 高为height, 验证码为vvcode的图片,图片中干扰线的条数为lineCnt
- * @param width 图片的宽
- * @param height 图片的高
- * @param vvcode 验证码字符串
- * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
- * @return 返回图片验证码
- */
- public static BufferedImage getImage(int width, int height, String vvcode, int lineCnt){
- return createImage(width, height, vvcode, lineCnt, 0.01);
- }
- /**
- * 生成一个宽为width, 高为height, 验证码为vvcode的图片,图片中干扰线的条数为lineCnt
- * 噪声比为noiseRate,即图片中噪音像素点的百分比
- * @param width 图片的宽
- * @param height 图片的高
- * @param vvcode 验证码字符串
- * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
- * @param noiseRate 图片中噪音像素点占总像素的百分比
- * @return 返回图片验证码
- */
- public static BufferedImage getImage(int width, int height, String vvcode, int lineCnt, double noiseRate){
- return createImage(width, height, vvcode, lineCnt, noiseRate);
- }
- /**
- *
- * 生成一个宽为width, 高为height, 验证码为vvcode的图片,图片中干扰线的条数为lineCnt
- * 噪声比为noiseRate,即图片中噪音像素点的百分比
- * @param width 图片的宽
- * @param height 图片的高
- * @param vvcode 验证码字符串
- * @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
- * @param noiseRate 图片中噪音像素点占总像素的百分比
- * @return 返回图片验证码
- */
- private static BufferedImage createImage(int width, int height, String vvcode, int lineCnt, double noiseRate){
- int fontWidth = ((int)(width * 0.8)) / vvcode.length();
- int fontHeight = (int)(height * 0.7);
- //为了在任意的width和height下都能生成良好的验证码,
- //字体的大小为fontWdith何fontHeight中的小者,
- int fontSize = Math.min(fontWidth, fontHeight);
- //drawString时要用到
- int paddingX = (int) (width * 0.1);
- int paddingY = height - (height - fontSize) / 2;
- //创建图像
- BufferedImage buffimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- //获得画笔
- Graphics g = buffimg.getGraphics();
- //设置画笔的颜色
- g.setColor(getRandColor(200, 255));
- //然后填充一个矩形,即设置背景色
- g.fillRect(0, 0, width, height);
- // 设置干扰线
- for (int i = 0; i < lineCnt; i++) {
- //随机获取干扰线的起点和终点
- int xs = (int)(Math.random() * width);
- int ys = (int)(Math.random() * height);
- int xe = (int)(Math.random() * width);
- int ye = (int)(Math.random() * height);
- g.setColor(getRandColor(1, 255));
- g.drawLine(xs, ys, xe, ye);
- }
- // 添加噪点
- int area = (int) (noiseRate * width * height);
- for(int i=0; i<area; ++i){
- int x = (int)(Math.random() * width);
- int y = (int)(Math.random() * height);
- buffimg.setRGB(x, y, (int)(Math.random() * 255));
- }
- //设置字体
- Font font = new Font("Ravie", Font.PLAIN, fontSize);
- g.setFont(font);
- for(int i=0; i<vvcode.length(); ++i){
- String ch = vvcode.substring(i, i+1);
- g.setColor(getRandColor(1, 199));
- g.drawString(ch, paddingX + fontWidth * i, paddingY);
- }
- return buffimg;
- }
- /**
- * 获取随机的颜色,r,g,b的取值在L到R之间
- * @param L 左区间
- * @param R 右区间
- * @return 返回随机颜色值
- */
- private static Color getRandColor(int L, int R){
- if(L > 255)
- L = 255;
- if(R > 255)
- R = 255;
- if(L < 0)
- L = 0;
- if(R < 0)
- R = 0;
- int interval = R - L;
- int r = L + (int)(Math.random() * interval);
- int g = L + (int)(Math.random() * interval);
- int b = L + (int)(Math.random() * interval);
- return new Color(r, g, b);
- }
- /**
- * 随机生成若干个由大小写字母和数字组成的字符串
- * @param len 随机生成len个字符
- * @return 返回随机生成的若干个由大小写字母和数字组成的字符串
- */
- public static String getRandvvcode(int len){
- String vvcode = "";
- for(int i=0; i<len; ++i){
- int index = (int)(Math.random() * ALPHABET.length());
- vvcode = vvcode + ALPHABET.charAt(index);
- }
- return vvcode;
- }
- /**
- * 将图片转为byte数组
- * @param image 图片
- * @return 返回byte数组
- * @throws IOException
- */
- public static byte[] getByteArray(BufferedImage image) throws IOException{
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ImageIO.write(image, "png", baos);
- return baos.toByteArray();
- //ByteArrayOutputStream 不需要close
- }
- //使用验证码图片
- //在verificationvvcode.java这个servlet中调用上面的类生成验证码图片,然后将图片返回给客户端。
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- HttpSession session = request.getSession();
- //随机生成字符串,并写入session
- String vcode = Verification.getRandvvcode(4);
- session.setAttribute("verification", vcode);
- BufferedImage image = com.fullgoal.ip.config.Verification.getImage(100,30, vcode, 5);
- response.setContentType("image/png");
- OutputStream out = response.getOutputStream();
- //com.fullgoal.ip.config.Verification为包名
- out.write(com.fullgoal.ip.config.Verification.getByteArray(image));
- out.flush();
- out.close();
- }
- }
J2EE验证码图片如何生成和点击刷新验证码
最新推荐文章于 2023-12-28 11:49:10 发布