用Java實現圖片驗證碼功能


一、什么是圖片驗證碼?

可以參考下面這張圖:

我們在一些網站注冊的時候,經常需要填寫以上圖片的信息。

1、圖片生成實體類:

  1 package com.hexianwei.graphic;
  2 
  3 import java.awt.Color;
  4 import java.awt.Font;
  5 import java.awt.Graphics2D;
  6 import java.awt.image.BufferedImage;
  7 import java.io.FileNotFoundException;
  8 import java.io.FileOutputStream;
  9 import java.io.IOException;
 10 import java.io.OutputStream;
 11 import java.util.Random;
 12 
 13 import javax.imageio.ImageIO;
 14 
 15 
 16 public class ImageVerificationCode {
 17 
 18     private int weight = 100;           //驗證碼圖片的長和寬
 19     private int height = 40;
 20     private String text;                //用來保存驗證碼的文本內容
 21     private Random r = new Random();    //獲取隨機數對象
 22     //private String[] fontNames = {"宋體", "華文楷體", "黑體", "微軟雅黑", "楷體_GB2312"};   //字體數組
 23     //字體數組
 24     private String[] fontNames = {"Georgia"};
 25     //驗證碼數組
 26     private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
 27 
 28     /**
 29      * 獲取隨機的顏色
 30      *
 31      * @return
 32      */
 33     private Color randomColor() {
 34         int r = this.r.nextInt(225);  //這里為什么是225,因為當r,g,b都為255時,即為白色,為了好辨認,需要顏色深一點。
 35         int g = this.r.nextInt(225);
 36         int b = this.r.nextInt(225);
 37         return new Color(r, g, b);            //返回一個隨機顏色
 38     }
 39 
 40     /**
 41      * 獲取隨機字體
 42      *
 43      * @return
 44      */
 45     private Font randomFont() {
 46         int index = r.nextInt(fontNames.length);  //獲取隨機的字體
 47         String fontName = fontNames[index];
 48         int style = r.nextInt(4);         //隨機獲取字體的樣式,0是無樣式,1是加粗,2是斜體,3是加粗加斜體
 49         int size = r.nextInt(10) + 24;    //隨機獲取字體的大小
 50         return new Font(fontName, style, size);   //返回一個隨機的字體
 51     }
 52 
 53     /**
 54      * 獲取隨機字符
 55      *
 56      * @return
 57      */
 58     private char randomChar() {
 59         int index = r.nextInt(codes.length());
 60         return codes.charAt(index);
 61     }
 62 
 63     /**
 64      * 畫干擾線,驗證碼干擾線用來防止計算機解析圖片
 65      *
 66      * @param image
 67      */
 68     private void drawLine(BufferedImage image) {
 69         int num = r.nextInt(10); //定義干擾線的數量
 70         Graphics2D g = (Graphics2D) image.getGraphics();
 71         for (int i = 0; i < num; i++) {
 72             int x1 = r.nextInt(weight);
 73             int y1 = r.nextInt(height);
 74             int x2 = r.nextInt(weight);
 75             int y2 = r.nextInt(height);
 76             g.setColor(randomColor());
 77             g.drawLine(x1, y1, x2, y2);
 78         }
 79     }
 80 
 81     /**
 82      * 創建圖片的方法
 83      *
 84      * @return
 85      */
 86     private BufferedImage createImage() {
 87         //創建圖片緩沖區
 88         BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB);
 89         //獲取畫筆
 90         Graphics2D g = (Graphics2D) image.getGraphics();
 91         //設置背景色隨機
 92         g.setColor(new Color(255, 255, r.nextInt(245) + 10));
 93         g.fillRect(0, 0, weight, height);
 94         //返回一個圖片
 95         return image;
 96     }
 97 
 98     /**
 99      * 獲取驗證碼圖片的方法
100      *
101      * @return
102      */
103     public BufferedImage getImage() {
104         BufferedImage image = createImage();
105         Graphics2D g = (Graphics2D) image.getGraphics(); //獲取畫筆
106         StringBuilder sb = new StringBuilder();
107         for (int i = 0; i < 4; i++)             //畫四個字符即可
108         {
109             String s = randomChar() + "";      //隨機生成字符,因為只有畫字符串的方法,沒有畫字符的方法,所以需要將字符變成字符串再畫
110             sb.append(s);                      //添加到StringBuilder里面
111             float x = i * 1.0F * weight / 4;   //定義字符的x坐標
112             g.setFont(randomFont());           //設置字體,隨機
113             g.setColor(randomColor());         //設置顏色,隨機
114             g.drawString(s, x, height - 5);
115         }
116         this.text = sb.toString();
117         drawLine(image);
118         return image;
119     }
120 
121     /**
122      * 獲取驗證碼文本的方法
123      *
124      * @return
125      */
126     public String getText() {
127         return text;
128     }
129 
130     public static void output(BufferedImage image, OutputStream out) throws IOException                  //將驗證碼圖片寫出的方法
131     {
132         ImageIO.write(image, "JPEG", out);
133     }
134 }

2、在控制器中把圖片響應給前端頁面

 1 @RequestMapping("getVerifiCode")
 2     @ResponseBody
 3     public void getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
 4         /*
 5              1.生成驗證碼
 6              2.把驗證碼上的文本存在session中
 7              3.把驗證碼圖片發送給客戶端
 8              */
 9         ImageVerificationCode ivc = new ImageVerificationCode();     //用我們的驗證碼類,生成驗證碼類對象
10         BufferedImage image = ivc.getImage();  //獲取驗證碼
11         request.getSession().setAttribute("text", ivc.getText()); //將驗證碼的文本存在session中
12         ivc.output(image, response.getOutputStream());//將驗證碼圖片響應給客戶端
13     }

3、從session獲得驗證碼字符

1 @RequestMapping("Login_authentication")
2     @ResponseBody
3     public String Login_authentication(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
4         request.setCharacterEncoding("utf-8");
5         String session_vcode=(String) request.getSession().getAttribute("text");    //從session中獲取真正的驗證碼
6         return session_vcode;
7     }

4、前端請求圖片

1 <a href="javascript:getVerifiCode()">
2     <img id="yzm_img" style="cursor:pointer;width: 100px;height: 36px;margin: 5px 0 0 5px;border-radius: 3px;" title="點擊刷新驗證碼" src="Mcake/getVerifiCode"/>
3 </a>
4 function getVerifiCode() {
5     $("#yzm_img").prop('src','Mcake/getVerifiCode?a='+new Date().getTime());
6 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM