欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java版仿QQ验证码风格图片验证码

程序员文章站 2024-03-11 14:20:43
本文为大家分享了java版仿qq验证码风格图片验证码,具体内容如下  功能包括:自定义图片尺寸和字符长度,随机背景颜色和字符颜色,随机字符偏移角度,字符平滑边缘...

本文为大家分享了java版仿qq验证码风格图片验证码,具体内容如下 

功能包括:自定义图片尺寸和字符长度,随机背景颜色和字符颜色,随机字符偏移角度,字符平滑边缘,干扰线,噪点,背景扭曲。
本来想做字符扭曲的,不知道怎的先生成文字再扭曲就报错了,先就这样吧,希望有高手能帮助修正一下。
需要说明的是之所以有几分像qq的验证码感觉是因为这个algerian字体,如果系统没有的话需要自行安装,百度搜字体名能下载到,丢系统fonts文件夹就行。

效果图:

Java版仿QQ验证码风格图片验证码

package hh.com.util;
 
import java.io.ioexception;
 
import javax.servlet.servletexception;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import javax.servlet.http.httpsession;
 
public class authimage extends javax.servlet.http.httpservlet implements javax.servlet.servlet {
 static final long serialversionuid = 1l;
 
 public void service(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
  response.setheader("pragma", "no-cache");
  response.setheader("cache-control", "no-cache");
  response.setdateheader("expires", 0);
  response.setcontenttype("image/jpeg");
   
  //生成随机字串
  string verifycode = verifycodeutils.generateverifycode(4);
  //存入会话session
  httpsession session = request.getsession(true);
  session.setattribute("rand", verifycode.tolowercase());
  //生成图片
  int w = 200, h = 80;
  verifycodeutils.outputimage(w, h, response.getoutputstream(), verifycode);
 
 }
}

verifycodeutils类

package hh.com.util;
 
import java.awt.color;
import java.awt.font;
import java.awt.graphics;
import java.awt.graphics2d;
import java.awt.lineargradientpaint;
import java.awt.paint;
import java.awt.renderinghints;
import java.awt.geom.affinetransform;
import java.awt.image.bufferedimage;
import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.outputstream;
import java.util.arrays;
import java.util.random;
 
import javax.imageio.imageio;
 
public class verifycodeutils{
 
 //使用到algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
 public static final string verify_codes = "23456789abcdefghjklmnpqrstuvwxyz";
 private static random random = new random();
 
 
 /**
  * 使用系统默认字符源生成验证码
  * @param verifysize 验证码长度
  * @return
  */
 public static string generateverifycode(int verifysize){
  return generateverifycode(verifysize, verify_codes);
 }
 /**
  * 使用指定源生成验证码
  * @param verifysize 验证码长度
  * @param sources 验证码字符源
  * @return
  */
 public static string generateverifycode(int verifysize, string sources){
  if(sources == null || sources.length() == 0){
   sources = verify_codes;
  }
  int codeslen = sources.length();
  random rand = new random(system.currenttimemillis());
  stringbuilder verifycode = new stringbuilder(verifysize);
  for(int i = 0; i < verifysize; i++){
   verifycode.append(sources.charat(rand.nextint(codeslen-1)));
  }
  return verifycode.tostring();
 }
  
 /**
  * 生成随机验证码文件,并返回验证码值
  * @param w
  * @param h
  * @param outputfile
  * @param verifysize
  * @return
  * @throws ioexception
  */
 public static string outputverifyimage(int w, int h, file outputfile, int verifysize) throws ioexception{
  string verifycode = generateverifycode(verifysize);
  outputimage(w, h, outputfile, verifycode);
  return verifycode;
 }
  
 /**
  * 输出随机验证码图片流,并返回验证码值
  * @param w
  * @param h
  * @param os
  * @param verifysize
  * @return
  * @throws ioexception
  */
 public static string outputverifyimage(int w, int h, outputstream os, int verifysize) throws ioexception{
  string verifycode = generateverifycode(verifysize);
  outputimage(w, h, os, verifycode);
  return verifycode;
 }
  
 /**
  * 生成指定验证码图像文件
  * @param w
  * @param h
  * @param outputfile
  * @param code
  * @throws ioexception
  */
 public static void outputimage(int w, int h, file outputfile, string code) throws ioexception{
  if(outputfile == null){
   return;
  }
  file dir = outputfile.getparentfile();
  if(!dir.exists()){
   dir.mkdirs();
  }
  try{
   outputfile.createnewfile();
   fileoutputstream fos = new fileoutputstream(outputfile);
   outputimage(w, h, fos, code);
   fos.close();
  } catch(ioexception e){
   throw e;
  }
 }
  
 /**
  * 输出指定验证码图片流
  * @param w
  * @param h
  * @param os
  * @param code
  * @throws ioexception
  */
 public static void outputimage(int w, int h, outputstream os, string code) throws ioexception{
  int verifysize = code.length();
  bufferedimage image = new bufferedimage(w, h, bufferedimage.type_int_rgb);
  random rand = new random();
  graphics2d g2 = image.creategraphics();
  g2.setrenderinghint(renderinghints.key_antialiasing,renderinghints.value_antialias_on);
  color[] colors = new color[5];
  color[] colorspaces = new color[] { color.white, color.cyan,
    color.gray, color.light_gray, color.magenta, color.orange,
    color.pink, color.yellow };
  float[] fractions = new float[colors.length];
  for(int i = 0; i < colors.length; i++){
   colors[i] = colorspaces[rand.nextint(colorspaces.length)];
   fractions[i] = rand.nextfloat();
  }
  arrays.sort(fractions);
   
  g2.setcolor(color.gray);// 设置边框色
  g2.fillrect(0, 0, w, h);
   
  color c = getrandcolor(200, 250);
  g2.setcolor(c);// 设置背景色
  g2.fillrect(0, 2, w, h-4);
   
  //绘制干扰线
  random random = new random();
  g2.setcolor(getrandcolor(160, 200));// 设置线条的颜色
  for (int i = 0; i < 20; i++) {
   int x = random.nextint(w - 1);
   int y = random.nextint(h - 1);
   int xl = random.nextint(6) + 1;
   int yl = random.nextint(12) + 1;
   g2.drawline(x, y, x + xl + 40, y + yl + 20);
  }
   
  // 添加噪点
  float yawprate = 0.05f;// 噪声率
  int area = (int) (yawprate * w * h);
  for (int i = 0; i < area; i++) {
   int x = random.nextint(w);
   int y = random.nextint(h);
   int rgb = getrandomintcolor();
   image.setrgb(x, y, rgb);
  }
   
  shear(g2, w, h, c);// 使图片扭曲
 
  g2.setcolor(getrandcolor(100, 160));
  int fontsize = h-4;
  font font = new font("algerian", font.italic, fontsize);
  g2.setfont(font);
  char[] chars = code.tochararray();
  for(int i = 0; i < verifysize; i++){
   affinetransform affine = new affinetransform();
   affine.settorotation(math.pi / 4 * rand.nextdouble() * (rand.nextboolean() ? 1 : -1), (w / verifysize) * i + fontsize/2, h/2);
   g2.settransform(affine);
   g2.drawchars(chars, i, 1, ((w-10) / verifysize) * i + 5, h/2 + fontsize/2 - 10);
  }
   
  g2.dispose();
  imageio.write(image, "jpg", os);
 }
  
 private static color getrandcolor(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 static int getrandomintcolor() {
  int[] rgb = getrandomrgb();
  int color = 0;
  for (int c : rgb) {
   color = color << 8;
   color = color | c;
  }
  return color;
 }
  
 private static int[] getrandomrgb() {
  int[] rgb = new int[3];
  for (int i = 0; i < 3; i++) {
   rgb[i] = random.nextint(255);
  }
  return rgb;
 }
 
 private static void shear(graphics g, int w1, int h1, color color) {
  shearx(g, w1, h1, color);
  sheary(g, w1, h1, color);
 }
  
 private static void shearx(graphics g, int w1, int h1, color color) {
 
  int period = random.nextint(2);
 
  boolean bordergap = true;
  int frames = 1;
  int phase = random.nextint(2);
 
  for (int i = 0; i < h1; i++) {
   double d = (double) (period >> 1)
     * math.sin((double) i / (double) period
       + (6.2831853071795862d * (double) phase)
       / (double) frames);
   g.copyarea(0, i, w1, 1, (int) d, 0);
   if (bordergap) {
    g.setcolor(color);
    g.drawline((int) d, i, 0, i);
    g.drawline((int) d + w1, i, w1, i);
   }
  }
 
 }
 
 private static void sheary(graphics g, int w1, int h1, color color) {
 
  int period = random.nextint(40) + 10; // 50;
 
  boolean bordergap = true;
  int frames = 20;
  int phase = 7;
  for (int i = 0; i < w1; i++) {
   double d = (double) (period >> 1)
     * math.sin((double) i / (double) period
       + (6.2831853071795862d * (double) phase)
       / (double) frames);
   g.copyarea(i, 0, 1, h1, 0, (int) d);
   if (bordergap) {
    g.setcolor(color);
    g.drawline(i, (int) d, i, 0);
    g.drawline(i, (int) d + h1, i, h1);
   }
 
  }
 
 }
 public static void main(string[] args) throws ioexception{
  file dir = new file("f:/verifies");
  int w = 200, h = 80;
  for(int i = 0; i < 50; i++){
   string verifycode = generateverifycode(4);
   file file = new file(dir, verifycode + ".jpg");
   outputimage(w, h, file, verifycode);
  }
 }
}

web.xml配置:

  <servlet>
   <servlet-name>authimage</servlet-name>
   <servlet-class>hh.com.util.authimage</servlet-class>
  </servlet>
  <servlet-mapping>
   <servlet-name>authimage</servlet-name>
  <url-pattern>/authimage</url-pattern>
  </servlet-mapping>

以上就是本文的全部内容,希望能够对大家学习java图片验证码有所启发。