import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Random; import javax.imageio.ImageIO; /** * 图片验证码生成工具类 * * @author tuozixuan */ public class ImageCodeHandler { // 图片宽度默认值 private int imageWidth = 100; // 图片高度默认值 private int imageHeight = 50; // 图片验证码长度 private int codeLength = 4; // 噪点率(噪点分布的疏密) private float yawpRate = 0.012f; // 字体大小 private int fontSize = 28; // 图片是否需要扭曲变形 private boolean isDistortion = true; // 图片验证码 private String imageCode = ""; // 输出的图片格式 private static final String imageFormat = "jpg"; // 0,1,2易和字母的o,l,z易混淆,不生成,可以生成汉字 private static char[] captchars = new char[] { '2', '3', '4', '5', '6', '7', '8', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y' }; /** * 把生成的验证码图片写到指定目录文件中 * * @param filePath 目录文件 * @throws IOException */ public void createImageFile(String filePath) throws IOException { OutputStream fos = new FileOutputStream(new File(filePath)); BufferedImage bufferedImage = createImage(getImageWidth(), getImageHeight()); ImageIO.write(bufferedImage, imageFormat, fos); } /** * 把创建好的图片验证码放入输出流中 * * @param os 输出流 * @throws IOException */ public String createImage(OutputStream os) throws IOException { BufferedImage bufferedImage = createImage(getImageWidth(), getImageHeight()); ImageIO.write(bufferedImage, imageFormat, os); return this.imageCode; } /** * 创建指定宽高的验证码图片对象 * * @param imageWidth 图片宽度 * @param imageHeight 图片高度 * @return BufferedImage 图片对象 */ public BufferedImage createImage(int imageWidth, int imageHeight) { // 创建一个指定宽高并带索引的字节图像对象 BufferedImage bufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_BYTE_INDEXED); // 创建一个二维图形对象以进行更复杂的图像绘制 Graphics2D graphics2D = bufferedImage.createGraphics(); // 设置背景色 Color color = getRandomColor(200, 250); graphics2D.setColor(color); // 填充指定宽高的矩形,其中x,y坐标为0 graphics2D.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight()); // 加字符 graphics2D.setColor(getRandomColor()); drawString(graphics2D, getCodeLength()); //drawCnString(graphics2D, getCodeLength()); // 加一道线 drawThickLine(graphics2D, 0, imageWidth / (2) + 1, imageWidth, imageHeight / (3) + 1, 4, getRandomColor(100, 200)); // 加干扰短线 setLTAttachLine(graphics2D, imageWidth, imageHeight); setRBAttachLine(graphics2D, imageWidth, imageHeight); // 使图片扭曲 if (isDistortion) { shear(graphics2D, bufferedImage.getWidth(), bufferedImage.getHeight(), color); } // 设置噪点 setYawp(bufferedImage, getYawpRate()); return bufferedImage; } /** * 在图片上画上字符 * * @param graphics2D 图形对象 * @param length 字符长度 */ private void drawString(Graphics2D graphics2D, int length) { int car = captchars.length - 1; Random random = new Random(); // 随机写字母或汉字 String text = ""; for (int i = 0; i < length; i++) { // 1.随机得到num个字母或数字 text += captchars[random.nextInt(car) + 1]; } this.imageCode = text; int xOffset = 1 + new Random().nextInt(40); int yOffset = 30; char[] charArray = text.toCharArray(); for (int i = 0; i < charArray.length; i++) { graphics2D.setFont(getRandomFont()); graphics2D.drawString(String.valueOf(charArray[i]), xOffset, yOffset); xOffset = xOffset + 14 + new Random().nextInt(5); } } private void drawCnString(Graphics2D graphics2D, int length) { int xOffset = 1 + new Random().nextInt(40); int yOffset = 30; for (int i = 0; i < length; i++) { graphics2D.setFont(getRandomCnFont()); graphics2D.drawString(String.valueOf(getRandomCnChar()), xOffset, yOffset); xOffset = xOffset + 20 + new Random().nextInt(5); } } /** * 从左上到右下加上多道干扰线 */ private static void setLTAttachLine(Graphics2D graphics2D, int imageWidth, int imageHeight) { int lineLeft = 7;// 从左上到右下的线条个数 Random random = new Random(); for (int i = 0; i < lineLeft; i++) { int x = random.nextInt(imageWidth - 1); int y = random.nextInt(imageHeight - 1); int xl = random.nextInt(6) + 1; int yl = random.nextInt(12) + 1; graphics2D.drawLine(x, y, x + xl + 40, y + yl + 20); } } /** * 从右上到左下加多道干扰线 */ private static void setRBAttachLine(Graphics2D graphics2D, int imageWidth, int imageHeight) { int lineRight = 8;// 从右上到左下的线条个数 Random random = new Random(); for (int i = 0; i < lineRight; i++) { int x = random.nextInt(imageWidth - 1); int y = random.nextInt(imageHeight - 1); int xl = random.nextInt(12) + 1; int yl = random.nextInt(6) + 1; graphics2D.drawLine(x, y, x - xl + 40, y - yl); } } /** * 设置噪点 * * @param bufferedImage 图片对象 * @param yawpRate 噪声率 */ private static void setYawp(BufferedImage bufferedImage, float yawpRate) { int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); int area = (int) (yawpRate * width * height); Random random = new Random(); for (int i = 0; i < area; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int rgb = getRandomIntColor(); bufferedImage.setRGB(x, y, rgb); } } 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]; Random random = new Random(); for (int i = 0; i < 3; i++) { rgb[i] = random.nextInt(255); } return rgb; } /** * 随机得到一个汉字的方法 * * @return char */ protected char getRandomCnChar() { final int minFirstByte = 176; final int maxFirstByte = 215; final int minSecondByte = 161; final int maxSecondByte = 249; byte[] b = new byte[2]; b[0] = (byte) (getRandomIntBetween(minFirstByte, maxFirstByte)); b[1] = (byte) (getRandomIntBetween(minSecondByte, maxSecondByte)); try { String s = new String(b, "gb2312"); System.out.println(s); assert s.length() == 1; return s.toCharArray()[0]; } catch (UnsupportedEncodingException uee) { // 重试 return getRandomCnChar(); } } /** * 获取两个整数之间的某个随机数,包含较小的整数,不包含较大的整数 * * @param first 第一个整数 * @param second 第二个整数 * @return */ private static int getRandomIntBetween(int first, int second) { Random random = new Random(); if (second < first) { int tmp = first; first = second; second = tmp; } return random.nextInt(second - first) + first; } /** * 产生随机字体 */ private Font getRandomFont() { Random random = new Random(); Font font[] = new Font[5]; int fontSize = getFontSize(); font[0] = new Font("Algerian", Font.PLAIN, fontSize); font[1] = new Font("Antique Olive Compact", Font.PLAIN, fontSize); font[2] = new Font("Fixedsys", Font.PLAIN, fontSize); font[3] = new Font("Algerian", Font.PLAIN, fontSize); font[4] = new Font("Arial", Font.PLAIN, fontSize); return font[random.nextInt(5)]; } /** * 产生随机中文字体 */ private Font getRandomCnFont() { Random random = new Random(); Font font[] = new Font[5]; int fontSize = getFontSize(); font[0] = new Font("微软雅黑", Font.PLAIN, fontSize); font[1] = new Font("宋体", Font.PLAIN, fontSize); font[2] = new Font("新宋体", Font.PLAIN, fontSize); font[3] = new Font("楷体", Font.PLAIN, fontSize); font[4] = new Font("幼圆", Font.PLAIN, fontSize); return font[random.nextInt(5)]; } /** * 给定范围获得随机颜色 * * @param fc 颜色范围-小 * @param bc 颜色范围-大 * @return Color 随机颜色 */ private static Color getRandomColor(int fc, int bc) { if (fc > 255) { fc = 255; } if (bc > 255) { bc = 255; } Random random = new Random(); 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 Color getRandomColor() { Random random = new Random(); Color color[] = new Color[10]; color[0] = new Color(32, 158, 25); color[1] = new Color(218, 42, 19); color[2] = new Color(31, 75, 208); return color[random.nextInt(3)]; } // 画一道粗线的方法 private static void drawThickLine(Graphics g, int x1, int y1, int x2, int y2, int thickness, Color c) { // The thick line is in fact a filled polygon g.setColor(c); int dX = x2 - x1; int dY = y2 - y1; // line length double lineLength = Math.sqrt(dX * dX + dY * dY); double scale = (double) (thickness) / (2 * lineLength); // The x and y increments from an endpoint needed to create a // rectangle... double ddx = -scale * (double) dY; double ddy = scale * (double) dX; ddx += (ddx > 0) ? 0.5 : -0.5; ddy += (ddy > 0) ? 0.5 : -0.5; int dx = (int) ddx; int dy = (int) ddy; // Now we can compute the corner points... int xPoints[] = new int[4]; int yPoints[] = new int[4]; xPoints[0] = x1 + dx; yPoints[0] = y1 + dy; xPoints[1] = x1 - dx; yPoints[1] = y1 - dy; xPoints[2] = x2 - dx; yPoints[2] = y2 - dy; xPoints[3] = x2 + dx; yPoints[3] = y2 + dy; g.fillPolygon(xPoints, yPoints, 4); } private static void shearX(Graphics g, int w1, int h1, Color color) { Random random = new Random(); 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) { Random random = new Random(); 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); } } } /** * 使图片扭曲 * * @param graphics 图形对象 * @param width 宽度 * @param height 高度 * @param color 颜色对象 */ private static void shear(Graphics graphics, int width, int height, Color color) { shearX(graphics, width, height, color); shearY(graphics, width, height, color); } public int getImageWidth() { return imageWidth; } public void setImageWidth(int imageWidth) { if (imageWidth > 0) { this.imageWidth = imageWidth; } } public int getImageHeight() { return imageHeight; } public void setImageHeight(int imageHeight) { if (imageHeight > 0) { this.imageHeight = imageHeight; } } public int getCodeLength() { return codeLength; } public void setCodeLength(int codeLength) { if (codeLength > 0) { this.codeLength = codeLength; } } public float getYawpRate() { return yawpRate; } public void setYawpRate(float yawpRate) { this.yawpRate = yawpRate; } public int getFontSize() { return fontSize; } public void setFontSize(int fontSize) { this.fontSize = fontSize; } public boolean isDistortion() { return isDistortion; } public void setDistortion(boolean isDistortion) { this.isDistortion = isDistortion; } }
使用示例:
import com.cogcn.framework.util.ImageCodeHandler; public class Test { public static void main(String[] args) throws Exception { ImageCodeHandler handler = new ImageCodeHandler(); handler.setCodeLength(4); handler.setImageWidth(100); handler.setImageHeight(50); handler.setYawpRate(0.2f); handler.setFontSize(18); handler.createImageFile("D:\\imageCode.jpg"); } }
相关推荐
1. ValidateCodeImageCodeMade.java:这可能是验证码生成类的名称,它包含了生成随机字符串和创建图像的逻辑。这个类可能包含生成验证码字符串的方法,以及将字符串转化为图像的方法。其中可能包括对字体、颜色、...
源码提供了一个生成图片验证码的工具类,适用于各种需要验证码的场景,如用户注册、...生成的验证码图片背景透明,线条清晰,可轻松辨认。本源码包含了工具类源码及调用示例,可供开发者参考使用,集成到您的项目中。
Java生成算数运算中文图片验证码的实现,结合了编程语言、图像处理和安全验证的多种技术,为用户提供了一种既安全又友好的验证方式。下面我们将深入探讨这个主题。 首先,验证码的核心是生成随机的算数运算表达式。...
Java随机生成验证码图片,适用于web登录验证等。个人觉得很不错~
在IT领域,验证码(CAPTCHA)是一...在提供的压缩包文件“图片验证码生成”中,可能包含了实现上述功能的源代码示例,你可以通过学习和理解这些代码,加深对Java生成图片验证码的理解,并根据实际需求进行调整和优化。
在本主题中,我们将深入探讨如何使用Java来生成图片验证码。Java生成图片验证码的过程涉及图像处理、随机数生成以及字符串编码等多个知识点。 首先,验证码的核心是生成一个随机的字符串,通常包含字母和数字。在...
java生成验证码的工具类,这个现在有依赖可以直接引入调用,但这个工具类没有引入依赖,大家也容易看懂代码,理解其含义。也可直接去工具类中调整生成验证码的宽度、高度、颜色、背景颜色、生成的随机数数量、干扰线...
Java servlet 自动生成 图片验证码 生成 Java源码
JAVA图片验证码 图片验证码JAVA图片验证码 图片验证码JAVA图片验证码 图片验证码JAVA图片验证码 图片验证码JAVA图片验证码 图片验证码JAVA图片验证码 图片验证码
70.java验证码生成.zip70.java验证码生成.zip70.java验证码生成.zip70.java验证码生成.zip70.java验证码生成.zip70.java验证码生成.zip70.java验证码生成.zip70.java验证码生成.zip70.java验证码生成.zip70.java...
在Java开发中,生成动态GIF验证码是一种常见的安全机制,用于防止自动机器人或者恶意脚本对网站进行非法操作。这种验证码通常包含随机生成的字母、数字或者符号,以动画的形式展示,用户需要输入看到的验证码才能...
JAVA实现随机图片验证码简单方法.rtf
图片生成随机位置 随机中文文字、随机抠图、拼图都只需要用到BufferedImage和Graphics2D。 3.2.前端熟悉点击事件,根据点击事件的坐标位置、图片的位置、浏览器的滚动位置算 出点击图片的相对位置;熟悉拖动原理...
本资源是java生成图片滑动验证码源码,具体使用可参考https://blog.csdn.net/shiqiangwen/article/details/89888092
csdn上三种java验证码生成方法,以及谷歌开源验证码,总共四种验证码生成集合。将生成的四个验证图片放在一个页面上以供比对,全部可以运行。 四种方法分别为: 1. 数字、字母、汉字混合验证码,叠影(给力)、扭曲 ...
这个工具类是用Java语言编写的,因此我们可以深入探讨一下Java验证码生成的相关技术和实现。 验证码(CAPTCHA,Completely Automated Public Turing test to tell Computers and Humans Apart)的主要目标是区分...
java 生成随机图片验证码 ,字母数组随机组合,加干扰线
这篇博客文章“java验证码生成类”提供了一个简单的示例,下面我们将深入探讨验证码生成的相关知识点。 首先,验证码的基本原理是生成一段随机的、难以由机器识别的文字或数字序列,然后要求用户在限定时间内输入这...
好看的图片验证码,包含干扰线、噪点、扭曲图片等。。
本教程将详细讲解如何在Java环境下实现一个完美的、可定制的验证码生成系统。 首先,验证码的基本原理是生成一串随机字符串,并将其与图像结合,用户在看到图像后需输入对应的字符串,服务器端会验证用户输入的字符...