輕量級驗證碼生成插件webutil-licenseImage源碼與實例應用


webutil-licenseImage 插件內置4種驗證碼樣式,支持用戶擴展.自定義樣式實現簡單驗證碼.

源碼脫管地址http://code.google.com/p/licenseimage/

Jar包下載地址: http://files.cnblogs.com/dennisit/Java%E9%AA%8C%E8%AF%81%E7%A0%81%E6%8F%92%E4%BB%B6.rar

 

項目結構圖:

說明:

ResourceUtil類為獲取包內資源服務
LicenseImage用來生成驗證碼

思路: 通過獲取驗證碼圖片資源,創建BufferedImage圖片對象,然后獲取該對象的Graphics2D操作類,使用Graphics2D繪制背景圖,繪制隨機生成的字碼,繪制干擾線,將結果封裝成Map集合,mapkey值用來做為session中判斷的依據,MapkeyBufferedImage對象,用於展示給前台輸出.

 

核心代碼如下:

ResourceUtil類

package org.pudp.util; import java.net.URL; import java.net.URLClassLoader; /** * 類說明: * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-9-16 * * org.pudp.util.Resource.java * */
public class ResourceUtil { /** * 獲取資源的URL路徑 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-9-16 下午09:33:07 * * @param paramString * 驗證碼圖片所在的包的相對路徑 * @return * 驗證碼所在的URL */
    public static URL getResourceUrl(String paramString){ return ((URLClassLoader)ResourceUtil.class.getClassLoader()).getResource(paramString); } /** * 獲取資源的串值路徑 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-9-16 下午06:09:17 * * @param paramString * 驗證碼圖片所在的包的相對路徑 * @return * 驗證碼所在的串值地址 */
    public static String getResourcePath(String paramString){ return Thread.currentThread().getContextClassLoader().getResource(paramString).getPath(); } }

生成驗證碼的核心類

package org.pudp.util.license; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Random; import javax.imageio.ImageIO; import org.pudp.util.ResourceUtil; /** * 類說明: 驗證碼工具 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-9-16 * * org.pudp.util.license.LicenseImage.java * */

public class LicenseImage { public static final Integer TYPE1 = 1;        //樣式一
    public static final Integer TYPE2 = 2;        //樣式二
    public static final Integer TYPE3 = 3;        //樣式三
    public static final Integer TYPE4 = 4;        //樣式四
    
    public static final int DEF_NUM = 4;            //驗證碼上的字符個數
    public static final int DEF_LINES = 3;             //干擾線條數
    public static final int DEF_WIDTH = 150;        //驗證碼圖片寬
    public static final int DEF_HEIGHT = 50;        //驗證碼圖片高
    public static final int DEF_FONT_SIZE = 24;        //驗證碼上字體大小
        
    private int num;                    //驗證碼上的字符個數
    private int width ;                    //驗證碼圖片寬
    private int height ;                //驗證碼圖片高
    private int fontSize ;                //驗證碼上字體大小
    private int lines ;                    //干擾線條數
 
    
    private static final String[] chars = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I" }; public LicenseImage(){ this(DEF_WIDTH, DEF_HEIGHT, DEF_FONT_SIZE, DEF_NUM, DEF_LINES); } /** * 自定義驗證碼的寬度與高度 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 */
    public LicenseImage(int width,int height){ if(width<0 || height<0){ this.width = LicenseImage.DEF_WIDTH; this.height = LicenseImage.DEF_HEIGHT; }else{ this.width = width; this.height = height; } this.num = LicenseImage.DEF_NUM; this.fontSize = LicenseImage.DEF_FONT_SIZE; this.lines = LicenseImage.DEF_LINES; } /** * 自定義驗證碼的寬度和高度,以及字體大小 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 * @param fontSize * 驗證碼字體大小 */
    public LicenseImage(int width,int height,int fontSize){ this(width, height); this.fontSize = fontSize; this.num = LicenseImage.DEF_NUM; this.lines = LicenseImage.DEF_LINES; } /** * 自定義驗證碼的寬度和高度,以及字體大小 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 * @param fontSize * 驗證碼字體大小 * * @param size * 驗證碼上字體個數 */
    public LicenseImage(int width,int height,int fontSize,int num){ this(width, height,fontSize); if(num <0){ this.num = LicenseImage.DEF_NUM; }else{ this.num = num; } this.lines = LicenseImage.DEF_LINES; } /** * 自定義驗證碼的寬度和高度,以及字體大小 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 * @param fontSize * 驗證碼字體大小 * @param size * 驗證碼上字體個數 * * @param lines * 驗證碼上的干擾線條數目 */
    
    public LicenseImage(int width,int height,int fontSize,int num,int lines){ this(width, height,fontSize,num); this.lines = lines; } /** * * 生成驗證碼,驗證碼圖片由用戶自己定義 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-9-16 下午08:13:53 * * @param backgroundPath * 用戶自定義的驗證碼的背景圖片 * @return * 驗證碼生成后的封裝對象 */
    public Map<String,BufferedImage> createImage(String backgroundPath){ //保存產生驗證碼真實值的串
        StringBuffer buffer = new StringBuffer(); //自定義圖片對象
        BufferedImage image = new BufferedImage(this.width,this.height,BufferedImage.TYPE_INT_RGB); Map<String,BufferedImage> map = new HashMap<String,BufferedImage>(); Graphics2D graphics = (Graphics2D) image.createGraphics(); graphics.setColor(Color.WHITE); // 初始化背景圖片
        try { Image bgImage = ImageIO.read(ResourceUtil.getResourceUrl(backgroundPath)); graphics.drawImage(bgImage,0,0,this.width,this.height,null); } catch (IOException e) { e.printStackTrace(); } Random random = new Random(); //畫隨機字符
        for(int i=0; i<this.num; i++){ //隨即獲取定義字符集中的一個元素
            int rand = random.nextInt(chars.length); graphics.setColor(randomColor()); graphics.setFont(new Font("Times New Roman",Font.BOLD+Font.ITALIC,this.fontSize)); /** **隨機縮放文字並將文字旋轉指定角度* start*/ Graphics2D g2d_word = (Graphics2D) graphics; AffineTransform trans = new AffineTransform(); trans.rotate(random.nextInt(10) * 3.14 / 90, 13 * i + 8, 7); // 縮放文字
            float scaleSize = random.nextFloat() +0.8f; if (scaleSize > 1f){ scaleSize = 1f; } trans.scale(scaleSize, scaleSize); g2d_word.setTransform(trans); /** **隨機縮放文字並將文字旋轉指定角度* end*/ graphics.drawString(chars[rand],(this.num*2)+(i)*this.width/this.num , this.height/2); buffer.append(chars[rand]); //將生成的字符串存入到buffer中,將來獲取時用於跟用戶輸入的值比較
 } //畫干擾線
        for(int i=1;i<=this.lines;i++){ graphics.setColor(randomColor()); graphics.drawLine(random.nextInt(this.width), random.nextInt(this.height), random.nextInt(this.width),random.nextInt(this.height)); if(i==this.lines){ Font font = new Font("Times New Roman",Font.PLAIN, this.fontSize-5); graphics.setFont(font); graphics.setColor(Color.GRAY); } } //畫一條折線 
        /* BasicStroke bs=new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL); //創建一個供畫筆選擇線條粗細的對象 graphics.setStroke(bs); //改變線條的粗細 graphics.setColor(randomColor()); //設置當前顏色為預定義顏色中的深灰色 int[] xPoints=new int[3]; int[] yPoints=new int[3]; for(int j=0;j<3;j++){ xPoints[j]=random.nextInt(WIDTH - 1); yPoints[j]=random.nextInt(HEIGHT - 1); } graphics.drawPolyline(xPoints, yPoints,3); */ map.put(buffer.toString(), image); return map; } /** * * 使用系統默認樣式 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-9-16 下午08:06:22 * * @param type * 工具內置的類型,用戶使用該類型即可用內置的樣式生成驗證碼 * @return * Map<驗證碼的值,驗證碼的圖片> */
    public  Map<String,BufferedImage> createImage(int type){ return createImage("org/pudp/util/license/resources/yzm"+type+".gif"); } /** * 隨即產生顏色 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-9-16 下午08:04:08 * * @return * <code>Color對象</code> */
    public static Color randomColor(){ Random random = new Random(); Color color = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256)); return color; } }


實例應用

創建servlet

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(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"); //使用驗證碼工具生成驗證碼
        LicenseImage licenseImage = new LicenseImage(); //使用驗證碼工具內置樣式
        Map<String,BufferedImage> licenseImg = licenseImage.createImage(LicenseImage.TYPE1); //獲取map集合中的值
        String key = (String)licenseImg.keySet().iterator().next(); //將驗證碼的key放入session中 //SessionUtil.session(request).setAttribute(CommonConstant.LicenseImageKey, key);
        System.out.println("session中的驗證碼值為:" + key); //獲取map集合中的圖片對象
        BufferedImage buffImg = licenseImg.get(key); ServletOutputStream out = response.getOutputStream(); ImageIO.write(buffImg, "jpeg", out); out.close(); }

內置樣式一效果圖

使用工具內置的樣式生成驗證碼代碼,licenseImage.createImage(int type)方法,傳遞系統內置的4種樣式即可生成驗證碼

        //使用驗證碼工具生成驗證碼
        LicenseImage licenseImage = new LicenseImage(); //使用驗證碼工具內置樣式
        Map<String,BufferedImage> licenseImg = licenseImage.createImage(LicenseImage.TYPE1);

系統后台為我們打印出了session中存放的驗證碼的串值如下:



開發者自定義驗證碼,構造自定義參數說明如下

   /** * 自定義驗證碼的寬度與高度 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 */
    public LicenseImage(int width,int height){ this.width = width; this.height = height; this.num = LicenseImage.DEF_NUM; this.fontSize = LicenseImage.DEF_FONT_SIZE; this.lines = LicenseImage.DEF_LINES; } /** * 自定義驗證碼的寬度和高度,以及字體大小 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 * @param fontSize * 驗證碼字體大小 */
    public LicenseImage(int width,int height,int fontSize){ this(width, height); this.fontSize = fontSize; this.num = LicenseImage.DEF_NUM; this.lines = LicenseImage.DEF_LINES; } /** * 自定義驗證碼的寬度和高度,以及字體大小 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 * @param fontSize * 驗證碼字體大小 * * @param size * 驗證碼上字體個數 */
    public LicenseImage(int width,int height,int fontSize,int num){ this(width, height,fontSize); this.num = num; this.lines = LicenseImage.DEF_LINES; } /** * 自定義驗證碼的寬度和高度,以及字體大小 * @param width * 驗證碼的寬度 * @param height * 驗證碼的高度 * @param fontSize * 驗證碼字體大小 * @param size * 驗證碼上字體個數 * * @param lines * 驗證碼上的干擾線條數目 */
    
    public LicenseImage(int width,int height,int fontSize,int num,int lines){ this(width, height,fontSize,num); this.lines = lines; }
View Code


自定義實例應用

//使用驗證碼工具提供的構造參數自定義相應的參數值
    LicenseImage licenseImage = new LicenseImage(120,50,18,5,5); //指定自定義背景包內的相對路徑
    Map<String,BufferedImage> licenseImg = licenseImage.createImage("definebk.png");

如果自定義圖片在com.define包下,傳遞的串值參數為

    Map<String,BufferedImage> licenseImg = licenseImage.createImage("com/define/definebk.png");

自定義實例效果圖


內置幾種樣式:

應用說明,見jar包里邊的readme.txt文件

 

轉載請注明出處:[http://www.cnblogs.com/dennisit/p/3325871.html]

在線交談


免責聲明!

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



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