package com.opslab.util.image; import com.opslab.util.image.GIF.GifEncoder; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Random; /** * 具体用于实现生成验证码图片的方法 */ public final class CaptchaUtil { protected static Font font = new Font("Verdana", Font.ITALIC|Font.BOLD, 28); // 字体 /** * 产生0--num的随机数,不包括num * @param num 数字 * @return int 随机数字 */ public static int num(int num) { return (new Random()).nextInt(num); } /** * 给定范围获得随机颜色 * @return Color 随机颜色 */ protected static Color color(int fc, int bc) { if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + num(bc - fc); int g = fc + num(bc - fc); int b = fc + num(bc - fc); return new Color(r, g, b); } public static boolean pngCaptcha(String randomStr,int width,int height,String file){ char[] strs = randomStr.toCharArray(); try(OutputStream out = new FileOutputStream(file)) { BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D)bi.getGraphics(); AlphaComposite ac3; Color color ; int len = strs.length; g.setColor(Color.WHITE); g.fillRect(0,0,width,height); for(int i=0;i<15;i++){ color = color(150, 250); g.setColor(color); g.drawOval(num(width), num(height), 5+num(10), 5+num(10)); } g.setFont(font); int h = height - ((height - font.getSize()) >>1), w = width/len, size = w-font.getSize()+1; for(int i=0;i<len;i++){ // 指定透明度 ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); g.setComposite(ac3); // 对每个字符都用随机颜色 color = new Color(20 + num(110), 30 + num(110), 30 + num(110)); g.setColor(color); g.drawString(strs[i]+"",(width-(len-i)*w)+size, h-4); } ImageIO.write(bi, "png", out); out.flush(); return true; }catch (IOException e){ return false; } } public static boolean gifCaptcha(String randomStr,int width,int height,String file){ char[] rands = randomStr.toCharArray(); int len = rands.length; try(OutputStream out = new FileOutputStream(file)) { // gif编码类,这个利用了洋人写的编码类,所有类都在附件中 GifEncoder gifEncoder = new GifEncoder(); //生成字符 gifEncoder.start(out); gifEncoder.setQuality(180); gifEncoder.setDelay(100); gifEncoder.setRepeat(0); BufferedImage frame; Color fontcolor[]=new Color[len]; for(int i=0;i<len;i++) { fontcolor[i]=new Color(20 + num(110), 20 + num(110), 20 + num(110)); } for(int i=0;i<len;i++) { frame=graphicsImage(fontcolor, rands, i,width,height,len); gifEncoder.addFrame(frame); frame.flush(); } gifEncoder.finish(); return true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; } /** * 画随机码图 * @param fontcolor 随机字体颜色 * @param strs 字符数组 * @param flag 透明度使用 * @return BufferedImage */ private static BufferedImage graphicsImage(Color[] fontcolor,char[] strs,int flag,int width,int height,int len){ BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); //或得图形上下文 //Graphics2D g2d=image.createGraphics(); Graphics2D g2d = (Graphics2D)image.getGraphics(); //利用指定颜色填充背景 g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, width, height); AlphaComposite ac3; int h = height - ((height - font.getSize()) >>1) ; int w = width/len; g2d.setFont(font); for(int i=0;i<len;i++) { ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i,len)); g2d.setComposite(ac3); g2d.setColor(fontcolor[i]); g2d.drawOval(num(width), num(height), 5+num(10), 5+num(10)); g2d.drawString(strs[i]+"", (width-(len-i)*w)+(w-font.getSize())+1, h-4); } g2d.dispose(); return image; } /** * 获取透明度,从0到1,自动计算步长 * @return float 透明度 */ private static float getAlpha(int i,int j,int len) { int num = i+j; float r = (float)1/len,s = (len+1) * r; return num > len ? (num *r - s) : num * r; } }