验证码图片生成

18 篇文章 0 订阅
7 篇文章 0 订阅

步骤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;





/**

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

* <p>

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

* <p>

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

* <p>

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

* <p>

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

* <p>

* 生成的串字母统一用小写,串的最大长度为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;

* <p>

* 输出到页面时需要设置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;

<img src="${url}">

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值