JAVA实践生成验证码图片
来源:互联网 发布:区块链的共识机制 算法 编辑:程序博客网 时间:2024/05/29 16:20
前言
以前一直很好奇,验证码是怎么做出来的,我会PS的时候,一致认为是PS画的,最近在玩Web,然后发现too young了,原来是代码生成的。
实现参考的博客作者:
永恒の_☆
博客地址:
http://blog.csdn.net/chenghui0317/article/details/12526439
成果
实现参考
关键词参考: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
- JAVA实践生成验证码图片
- Java生成图片验证码
- Java生成验证码图片
- Java生成图片验证码
- Java生成图片验证码
- JAVA 生成验证码图片
- Java生成图片验证码
- Java生成验证码图片
- java生成验证码图片
- java生成验证码图片
- java 生成图片验证码
- java生成图片验证码
- java验证码图片生成
- JAVA生成图片验证码
- JAVA生成图片验证码
- java--生成图片验证码
- java生成图片验证码
- Java生成图片验证码
- PAT乙级(Basic Level)1042(Java)
- 查出区间整数
- Stress中常见问题及相关logcat
- Visual Studio开始Python编程 && Windows下用PyCharm
- python爬虫demo
- JAVA实践生成验证码图片
- android studio 主线程中访问网络,遇到android.os.NetworkOnMainThreadException
- uploadify 出现 IO Error 修改php-ini
- PercentRelativeLayout百分比布局
- 深入剖析Java中的装箱和拆箱
- ASP.NET与HTML的关系理解
- 3529: [Sdoi2014]数表
- SQL语句大全及实例
- PL/SQL database character set(AL32UTF8) and Client character set(ZHS16GBK) are different