当前位置: 移动技术网 > IT编程>开发语言>Java > Java版仿QQ验证码风格图片验证码

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

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

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

效果图:

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图片验证码有所启发。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网