图片验证码常用方法
- 获得随机颜色
1 private static Color getRandomColor() { 2 return new Color(random.nextInt(255), random.nextInt(255),random.nextInt(255)); 3 }
- 获得颜色的反色
1 private static Color getReverseColor(Color c) { 2 return new Color(255 - c.getRed(), 255 - c.getGreen(),255 - c.getBlue()); 3 }
- 绘制噪音点
1 private static void drawNoisePoint(int width, int height, int num,Graphics2D g) { 2 for (int i = 0, n = random.nextInt(num); i < n; i++) {// 绘制最多num个噪音点 3 g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);// 随机噪音点 4 } 5 }
- 绘制干扰线
1 private static void drawInterferingLine(int width, int height, int n,Graphics2D g) { 2 for (int i = 0; i < n; i++) { 3 int x = random.nextInt(width - 1); 4 int y = random.nextInt(height - 1); 5 int xl = random.nextInt(6) + 1; 6 int yl = random.nextInt(12) + 1; 7 g.drawLine(x, y, x + xl + 40, y + yl + 20); 8 } 9 }
- 扭曲图片
1 private static void shear(int width, int height, Graphics2D g, Color color) { 2 shearX(g, width, height, color); 3 shearY(g, width, height, color); 4 }
- 沿Y轴扭曲
1 private static void shearY(Graphics2D g, int width, int height, Color color) { 2 int period = random.nextInt(40) + 10; // 周期 3 int frames = 20; // 帧 4 int phase = 7; // 相位 5 for (int i = 0; i < width; i++) { 6 double d = (double) (period >> 1)* Math.sin((double) i / (double) period + (Math.PI * 2 * (double) phase) / (double) frames); 7 g.copyArea(i, 0, 1, height, 0, (int) d); 8 g.setColor(color); 9 g.drawLine(i, (int) d, i, 0); 10 g.drawLine(i, (int) d + height, i, height); 11 } 12 }
- 沿X轴扭曲
1 private static void shearX(Graphics2D g, int width, int height, Color color) { 2 int period = random.nextInt(2); 3 int frames = 1; 4 int phase = random.nextInt(2); 5 for (int i = 0; i < height; i++) { 6 double d = (double) (period >> 1)* Math.sin((double) i / (double) period + (Math.PI * 2 * (double) phase) / (double) frames); 7 g.copyArea(0, i, width, 1, (int) d, 0); 8 g.setColor(color); 9 g.drawLine((int) d, i, 0, i); 10 g.drawLine((int) d + width, i, width, i); 11 } 12 }
- 创建验证码图片
1 public static void outputImage(int width, int height, OutputStream os,String randomString) throws IOException { 2 int verifySize = randomString.length(); // 验证码长度 3 Color color = getRandomColor();// 随机颜色,用于背景色 4 Color reverse = getReverseColor(color);// 反色,用于前景色 5 6 BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);// 创建一个彩色图片 7 8 Graphics2D g = bi.createGraphics();// 获取绘图对象 9 10 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); // 设置图像抗锯齿 11 g.setFont(new Font(Font.SANS_SERIF, Font.ITALIC, height - 4));// 设置字体: Serif的意思是,在字的笔划开始及结束的地方有额外的装饰,而且笔划的粗细会因直横的不同而有不同。相反的,Sans Serif则没有这些额外的装饰,笔划粗细大致差不多 12 g.setColor(color);// 设置颜色 13 g.fillRect(0, 0, width, height);// 绘制背景:用这个颜色填充这个区域 14 g.setColor(reverse);// 设置颜色 15 16 for (int i = 0; i < verifySize; i++) { // 绘制验证码 17 g.drawChars(randomString.toCharArray(), i, 1,((width - 10) / verifySize) * i + 5, height / 2 + height/ 2 - 10); 18 } 19 20 drawNoisePoint(width, height, 500, g); // 绘制最多1000个噪音点 21 22 drawInterferingLine(width, height, 30, g); // 产生30条干扰线 23 24 shear(width, height, g, color);// 使图片扭曲 25 26 g.dispose();// 释放由此 Window、其子组件及其拥有的所有子组件所使用的所有本机屏幕资源 27 28 ImageIO.write(bi, "jpg", os); 29 }
- 生成指定验证码图片文件
1 public static void outputImageFile(int width, int height, File file,String code) throws IOException { 2 if (file == null) { 3 return; 4 } 5 File dir = file.getParentFile();// 获得父目录 6 if (!dir.exists()) { // 如果父目录不存在,则创建一个 7 dir.mkdirs(); 8 } 9 try { 10 file.createNewFile(); 11 FileOutputStream fos = new FileOutputStream(file); 12 outputImage(width, height, fos, code); // 创建验证码图片 13 fos.close(); // 关闭流 14 } catch (IOException e) { 15 throw e; 16 } 17 }
转自:http://blog.csdn.net/paulangsky/article/details/52191696