JAVA实践生成验证码图片

来源:互联网 发布:区块链的共识机制 算法 编辑:程序博客网 时间:2024/05/29 16:20

前言

以前一直很好奇,验证码是怎么做出来的,我会PS的时候,一致认为是PS画的,最近在玩Web,然后发现too young了,原来是代码生成的。

实现参考的博客作者:
永恒の_☆
博客地址:
http://blog.csdn.net/chenghui0317/article/details/12526439

成果

chapter
chapter

实现参考

关键词参考:BufferedImageGraphics2DImageIO利用Graphics2D的drawString方法可以很方便的绘制字符。主要是如何让字符不粘在一起,只要设置一个偏移量,每次循环就增加一倍偏移量。另外一个就是添加干扰线,一定程度上可以防止自动登录。。然而除非把验证码弄得面目全非,否则还是很容易被识别的。另外我尝试了进行扭曲,然后扭曲失败了,效果惨不忍睹,人眼都看不出来- -网上搜到的感觉略高端,又不是研究这方面的,就没继续深入了解。(逃

代码实现

import javax.imageio.ImageIO;import java.awt.image.BufferedImage;import java.awt.Graphics2D;import java.awt.Color;import java.awt.Font;import java.awt.GraphicsEnvironment;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Random;public class GetPic {    public static void main(String[] args) {        int codeCount = 4;        String suffix = "png";        String picName = "chapter";        //picName = null;        String chapter = generateImg(codeCount, picName, suffix);        System.out.println(chapter);    }    /**     *  生成验证码图片,并返回验证码的值     * @param codeCount 验证码个数     * @param picName 图片文件名     * @param suffix    图片文件格式(png/jpeg)     * @return  验证码的值     */    public static String generateImg(int codeCount, String picName, String suffix) {        //图片的宽和高        int imgWidth = codeCount * 20;        int imgHeight = 30;        BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_BGR);        String chapter = drawImg(buffImg, codeCount, imgWidth, imgHeight);        //如果图片文件名为空,那么使用验证码的值作为图片文件名        picName = picName == null ? chapter : picName;        outputPic(buffImg, picName, suffix);        return chapter;    }    /**     *  根据宽度、高度、和验证码的个数绘制验证码图片,并返回验证码的值     * @param buffImg   BufferedImage对象     * @param codeCount 验证码个数     * @param imgWidth  图片宽度     * @param imgHeight 图片高度     * @return  验证码的值     */    private static String drawImg(BufferedImage buffImg, int codeCount, int imgWidth, int imgHeight) {        Random rand = new Random();        Graphics2D gd = buffImg.createGraphics();        //填充矩形        gd.setColor(Color.WHITE);        gd.fillRect(0, 0, imgWidth, imgHeight);        //设置字体        Font font = new Font("微软雅黑", Font.PLAIN, imgHeight - 5);        gd.setFont(font);        //绘制边框        gd.setColor(Color.BLACK);        gd.drawRect(0, 0, imgWidth - 1, imgHeight - 1);        //绘制灰色干扰线        gd.setColor(Color.GRAY);        for (int i = 0, x, y, x1, y1; i < 30; i++) {            x = rand.nextInt(imgWidth);            y = rand.nextInt(imgHeight);            x1 = rand.nextInt(12);            y1 = rand.nextInt(12);            gd.drawLine(x, y, x + x1, y + y1);        }        //int codeCount = 4,        int codeX = 15, codeY = 25;        //记录验证码        StringBuffer chapter = new StringBuffer();        //临时变量        String strRand;        char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',                'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',                'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };        for (int i = 0, red, green, blue; i < codeCount; i++) {            //随机获取字符            strRand = String.valueOf(codeSequence[rand.nextInt(codeSequence.length)]);            //随机选择字符颜色            red = rand.nextInt(255);            green = rand.nextInt(255);            blue = rand.nextInt(255);            gd.setColor(new Color(red, green, blue));            //绘制字符            gd.drawString(strRand, (i + 1) * codeX, codeY);            //记录字符            chapter.append(strRand);        }        return chapter.toString();    }    /**     *  将绘制完毕的图片输出成文件     * @param buffImg   绘制完毕的验证码图片     * @param fileName  文件名     * @param suffix    后缀(png/jpeg)     */    public static void outputPic(BufferedImage buffImg, String fileName, String suffix) {        try {            int index = 1;            File file = new File(fileName + "." + suffix);            while (file.exists()) {                file = new File(fileName + "(" + (index++) + ")." + suffix);            }            FileOutputStream fos = new FileOutputStream(file);            ImageIO.write(buffImg, suffix, fos);            fos.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 显示字体列表     */    public static void showFontList() {        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();        String[] fonts = ge.getAvailableFontFamilyNames();        for (String font : fonts) {            System.out.println(font);        }    }    //试图扭曲图片,失败了    /*    public static void getImgArr(BufferedImage buffImg) {        int offX = 20;        int offY = 20;        int height = buffImg.getHeight();        int width = buffImg.getWidth();        System.out.println("width:" + width + " height:" + height);        int[][] rgbs = new int[width][height];        for (int i = buffImg.getMinY(); i < width; i++) {            for (int j = buffImg.getMinX(); j < height; j++) {                if (i - offX  < width && i - offX >= 0) {                    buffImg.setRGB(i - offX, j, buffImg.getRGB(i, j));                }                //if (j - offY  < height && j - offY >= 0) {                    //buffImg.setRGB(i, j - offY, buffImg.getRGB(i, j));                //}            }            //offY -= 2;            offX--;        }    }*/}

END

0 0
原创粉丝点击