生成一张(x=250,y=150)的验证码图片
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//生成图片
ServletOutputStream sos = resp.getOutputStream(); //二进制通道,输出
ImageIO.write(generatePic(250, 150), "JPG", sos); //类
sos.flush(); //刷新资源
sos.close(); //关闭资源
}
在generatePic类中定义一个2d图片的对象 g,背景默认为黑色
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D)image.getGraphics(); //强制转化为2d图片
把黑色背景粉刷成渐变色
for(int i=0;i<width;i+=5) {
Random random=new Random();
g.setColor(new Color(random.nextInt(15)+240, random.nextInt(15)+240,random.nextInt(15)+240)); //生成渐变背景色
g.fillRect(i, 0, width, height); //填充图片
}
随机生成噪点,画到图片上
for(int i=0;i<50;i++){ //生成噪点,生成50个噪点
Random random=new Random();
int x= random.nextInt(width); //随机生成0~250的数
int y=random.nextInt(height); //随机生成0~150的数
g.setColor(new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256))); //每次循环变换一次颜色
g.drawOval(x,y,10,10); //随机画圈
}
随机生成线条,画到图片上
for(int i=0;i<45;i++){ //生成线条
Random random=new Random();
int x= random.nextInt(width); //随机生成0~250的数
int y=random.nextInt(height); //随机生成0~150的数
g.setColor(new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256))); //每次循环变换一次颜色
if(i%2==1) //如果判断结果为真,则画竖线
g.drawLine(x,y,x,x);
else //如果判断结果为假,则画横线
g.drawLine(x,y,y,y);
}
新建一个类randString,随机生成字符
public static String randString(int count){
String text="QWERTYUIOPLKJHGFDSAZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm"; //字符串库
Random random=new Random();
String nextrandom="";
for(int i=0;i<count;i++){
nextrandom+=text.charAt(random.nextInt(text.length())); //循环添加随机字符
}
return nextrandom;
}
新建一个类randint,用来固定字符串的位置
public static int randint(int a,int b){
Random random=new Random();
int nextint=random.nextInt(b-a);
nextint+=a;
return nextint;
}
循环把字符画到图片上
String text =CaptcheController.randString(4); //生成4个随机随机字符
for(int i=0;i<text.length();i++){
Random random=new Random();
g.setFont(new Font("宋体",Font.BOLD,randint((int)(width*0.2),(int)(height*0.6)))); //设置字体,字号随着图片大小而改变
g.setColor(new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256))); //设置字体的颜色,在0~255之间,每次循环更改一次颜色
AffineTransform aff=g.getTransform();
double radis=Math.toRadians(random.nextInt(141)+(-70)); //旋转的角度,在-70~70之间旋转
int x=(int)(width*0.2); //设置字体的坐标
int y=(int)(height*0.5); //设置字体的y坐标
g.rotate(radis,125,75); //旋转图片,为下一个旋转做准备
g.drawString(text.charAt(i)+"",x*i+x,y); //每次循环写入字体
g.setTransform(aff); //旋转字体
}
g.dispose(); //释放2d图片