java图片验证码

由于业务需要接触到权限控制这一块,网上找到大神的资料 https://www.sojson.com/shiro从其中摘录出验证码部分做个记录防止以后忘记。

1.创建验证码对象

1 public class     Verify {
2 private String code;//如1+2
3 private Interager value;//如3
4  //省略getter和setter 
5  }

2. 生成验证码字符串

 1  /** 
 2      * 使用指定源生成验证码 
 3      * @param verifySize    验证码长度 
 4      * @param sources   验证码字符源 
 5      * @return 
 6      */  
 7     public static String generateVerifyCode(int verifySize, String sources){  
 8         if(sources == null || sources.length() == 0){  
 9             sources = VERIFY_CODES;  
10         }  
11         int codesLen = sources.length();  
12         Random rand = new Random(System.currentTimeMillis());  
13         StringBuilder verifyCode = new StringBuilder(verifySize);  
14         for(int i = 0; i < verifySize; i++){  
15             verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));  
16         }  
17         return verifyCode.toString();  
18     }  

3.生成验证码图片,主要应用java.awt包下的一些工具本人不是很熟悉

  1    /** 
  2      * 生成指定验证码图像文件 
  3      * @param w 
  4      * @param h 
  5      * @param outputFile 
  6      * @param code 
  7      * @throws IOException 
  8      */  
  9     public static void outputImage(int w, int h, File outputFile, String code) throws IOException{  
 10         if(outputFile == null){  
 11             return;  
 12         }  
 13         File dir = outputFile.getParentFile();  
 14         if(!dir.exists()){  
 15             dir.mkdirs();  
 16         }  
 17         try{  
 18             outputFile.createNewFile();  
 19             FileOutputStream fos = new FileOutputStream(outputFile);  
 20             outputImage(w, h, fos, code);  
 21             fos.close();  
 22         } catch(IOException e){  
 23             throw e;  
 24         }  
 25     }  
 26       
 27     /** 
 28      * 输出指定验证码图片流 
 29      * @param w 
 30      * @param h 
 31      * @param os 
 32      * @param code 
 33      * @throws IOException 
 34      */  
 35     public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{  
 36         int verifySize = code.length();  
 37         BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
 38         Random rand = new Random();  
 39         Graphics2D g2 = image.createGraphics();  
 40         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);  
 41         Color[] colors = new Color[5];  
 42         Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,  
 43                 Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,  
 44                 Color.PINK, Color.YELLOW };  
 45         float[] fractions = new float[colors.length];  
 46         for(int i = 0; i < colors.length; i++){  
 47             colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];  
 48             fractions[i] = rand.nextFloat();  
 49         }  
 50         Arrays.sort(fractions);  
 51           
 52         g2.setColor(Color.GRAY);// 设置边框色  
 53         g2.fillRect(0, 0, w, h);  
 54           
 55         Color c = getRandColor(200, 250);  
 56         g2.setColor(c);// 设置背景色  
 57         g2.fillRect(0, 2, w, h-4);  
 58           
 59         //绘制干扰线  
 60         Random random = new Random();  
 61         g2.setColor(getRandColor(160, 200));// 设置线条的颜色  
 62         for (int i = 0; i < 20; i++) {  
 63             int x = random.nextInt(w - 1);  
 64             int y = random.nextInt(h - 1);  
 65             int xl = random.nextInt(6) + 1;  
 66             int yl = random.nextInt(12) + 1;  
 67             g2.drawLine(x, y, x + xl + 40, y + yl + 20);  
 68         }  
 69           
 70         // 添加噪点  
 71         float yawpRate = 0.05f;// 噪声率  
 72         int area = (int) (yawpRate * w * h);  
 73         for (int i = 0; i < area; i++) {  
 74             int x = random.nextInt(w);  
 75             int y = random.nextInt(h);  
 76             int rgb = getRandomIntColor();  
 77             image.setRGB(x, y, rgb);  
 78         }  
 79           
 80         shear(g2, w, h, c);// 使图片扭曲  
 81   
 82         g2.setColor(getRandColor(100, 160));  
 83         int fontSize = h-4;  
 84         Font font = new Font("Algerian", Font.ITALIC, fontSize);  
 85         g2.setFont(font);  
 86         char[] chars = code.toCharArray();  
 87         for(int i = 0; i < verifySize; i++){  
 88             AffineTransform affine = new AffineTransform();  
 89             affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);  
 90             g2.setTransform(affine);  
 91             g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);  
 92         }  
 93           
 94         g2.dispose();  
 95         ImageIO.write(image, "jpg", os);  
 96     }  
 97       
 98     private static Color getRandColor(int fc, int bc) {  
 99         if (fc > 255)  
100             fc = 255;  
101         if (bc > 255)  
102             bc = 255;  
103         int r = fc + random.nextInt(bc - fc);  
104         int g = fc + random.nextInt(bc - fc);  
105         int b = fc + random.nextInt(bc - fc);  
106         return new Color(r, g, b);  
107     }  
108       
109     private static int getRandomIntColor() {  
110         int[] rgb = getRandomRgb();  
111         int color = 0;  
112         for (int c : rgb) {  
113             color = color << 8;  
114             color = color | c;  
115         }  
116         return color;  
117     }  
118       
119     private static int[] getRandomRgb() {  
120         int[] rgb = new int[3];  
121         for (int i = 0; i < 3; i++) {  
122             rgb[i] = random.nextInt(255);  
123         }  
124         return rgb;  
125     }  
126   
127     private static void shear(Graphics g, int w1, int h1, Color color) {  
128         shearX(g, w1, h1, color);  
129         shearY(g, w1, h1, color);  
130     }  
131       
132     private static void shearX(Graphics g, int w1, int h1, Color color) {  
133   
134         int period = random.nextInt(2);  
135   
136         boolean borderGap = true;  
137         int frames = 1;  
138         int phase = random.nextInt(2);  
139   
140         for (int i = 0; i < h1; i++) {  
141             double d = (double) (period >> 1)  
142                     * Math.sin((double) i / (double) period  
143                             + (6.2831853071795862D * (double) phase)  
144                             / (double) frames);  
145             g.copyArea(0, i, w1, 1, (int) d, 0);  
146             if (borderGap) {  
147                 g.setColor(color);  
148                 g.drawLine((int) d, i, 0, i);  
149                 g.drawLine((int) d + w1, i, w1, i);  
150             }  
151         }  
152   
153     }  
154   
155     private static void shearY(Graphics g, int w1, int h1, Color color) {  
156   
157         int period = random.nextInt(40) + 10; // 50;  
158   
159         boolean borderGap = true;  
160         int frames = 20;  
161         int phase = 7;  
162         for (int i = 0; i < w1; i++) {  
163             double d = (double) (period >> 1)  
164                     * Math.sin((double) i / (double) period  
165                             + (6.2831853071795862D * (double) phase)  
166                             / (double) frames);  
167             g.copyArea(i, 0, 1, h1, 0, (int) d);  
168             if (borderGap) {  
169                 g.setColor(color);  
170                 g.drawLine(i, (int) d, i, 0);  
171                 g.drawLine(i, (int) d + h1, i, h1);  
172             }  
173   
174         }  
175   
176     }  

4.最后贴源代码。整体流程,

  1 import java.awt.Color;
  2 import java.awt.Font;
  3 import java.awt.Graphics;
  4 import java.awt.Graphics2D;
  5 import java.awt.RenderingHints;
  6 import java.awt.geom.AffineTransform;
  7 import java.awt.image.BufferedImage;
  8 import java.io.File;
  9 import java.io.FileOutputStream;
 10 import java.io.IOException;
 11 import java.io.OutputStream;
 12 import java.util.Arrays;
 13 import java.util.Random;
 14 
 15 import javax.imageio.ImageIO;
 16 
 17 import com.sojson.core.shiro.token.manager.TokenManager;//这个主要是shiro框架下的token管理器
 18   
 19 public class VerifyCodeUtils{  
 20   
 21     //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符  
 22     public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";  
 23     //验证码的Key
 24     public static final String V_CODE = "_CODE";
 25     private static Random random = new Random();  
 26   
 27     
 28     /**
 29      * 验证码对象
 30      * @author zhou-baicheng
 31      *
 32      */
 33     public static class Verify{
 34         
 35         private String code;//如 1 + 2
 36         
 37         private Integer value;//如  3
 38 
 39         public String getCode() {
 40             return code;
 41         }
 42 
 43         public void setCode(String code) {
 44             this.code = code;
 45         }
 46 
 47         public Integer getValue() {
 48             return value;
 49         }
 50 
 51         public void setValue(Integer value) {
 52             this.value = value;
 53         }
 54     }
 55   
 56     /** 
 57      * 使用系统默认字符源生成验证码 
 58      * @param verifySize    验证码长度 
 59      * @return 
 60      */  
 61     public static Verify generateVerify(){  
 62         int number1 = new Random().nextInt(10) + 1;;
 63         int number2 = new Random().nextInt(10) + 1;;
 64         Verify entity = new Verify();
 65         entity.setCode(number1  + " x " + number2);
 66         entity.setValue(number1 + number2);
 67         return entity;
 68     }  
 69     
 70     /** 
 71      * 使用系统默认字符源生成验证码 
 72      * @param verifySize    验证码长度 
 73      * @return 
 74      */  
 75     public static String generateVerifyCode(int verifySize){  
 76         return generateVerifyCode(verifySize, VERIFY_CODES);  
 77     }  
 78     /**
 79      * 清除验证码
 80      */
 81     public static void clearVerifyCode(){
 82         TokenManager.getSession().removeAttribute(V_CODE);
 83     }
 84     
 85     /**
 86      * 对比验证码   
 87      */
 88     public static boolean verifyCode(String code){
 89         String v = (String)TokenManager.getVal2Session(V_CODE);
 90         return StringUtils.equals(v, StringUtils.lowerCase(code));
 91     }
 92     
 93     /** 
 94      * 使用指定源生成验证码 
 95      * @param verifySize    验证码长度 
 96      * @param sources   验证码字符源 
 97      * @return 
 98      */  
 99     public static String generateVerifyCode(int verifySize, String sources){  
100         if(sources == null || sources.length() == 0){  
101             sources = VERIFY_CODES;  
102         }  
103         int codesLen = sources.length();  
104         Random rand = new Random(System.currentTimeMillis());  
105         StringBuilder verifyCode = new StringBuilder(verifySize);  
106         for(int i = 0; i < verifySize; i++){  
107             verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));  
108         }  
109         return verifyCode.toString();  
110     }  
111       
112     /** 
113      * 生成随机验证码文件,并返回验证码值 
114      * @param w 
115      * @param h 
116      * @param outputFile 
117      * @param verifySize 
118      * @return 
119      * @throws IOException 
120      */  
121     public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{  
122         String verifyCode = generateVerifyCode(verifySize);  
123         outputImage(w, h, outputFile, verifyCode);  
124         return verifyCode;  
125     }  
126       
127     /** 
128      * 输出随机验证码图片流,并返回验证码值 
129      * @param w 
130      * @param h 
131      * @param os 
132      * @param verifySize 
133      * @return 
134      * @throws IOException 
135      */  
136     public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{  
137         String verifyCode = generateVerifyCode(verifySize);  
138         outputImage(w, h, os, verifyCode);  
139         return verifyCode;  
140     }  
141       
142     /** 
143      * 生成指定验证码图像文件 
144      * @param w 
145      * @param h 
146      * @param outputFile 
147      * @param code 
148      * @throws IOException 
149      */  
150     public static void outputImage(int w, int h, File outputFile, String code) throws IOException{  
151         if(outputFile == null){  
152             return;  
153         }  
154         File dir = outputFile.getParentFile();  
155         if(!dir.exists()){  
156             dir.mkdirs();  
157         }  
158         try{  
159             outputFile.createNewFile();  
160             FileOutputStream fos = new FileOutputStream(outputFile);  
161             outputImage(w, h, fos, code);  
162             fos.close();  
163         } catch(IOException e){  
164             throw e;  
165         }  
166     }  
167       
168     /** 
169      * 输出指定验证码图片流 
170      * @param w 
171      * @param h 
172      * @param os 
173      * @param code 
174      * @throws IOException 
175      */  
176     public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{  
177         int verifySize = code.length();  
178         BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
179         Random rand = new Random();  
180         Graphics2D g2 = image.createGraphics();  
181         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);  
182         Color[] colors = new Color[5];  
183         Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,  
184                 Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,  
185                 Color.PINK, Color.YELLOW };  
186         float[] fractions = new float[colors.length];  
187         for(int i = 0; i < colors.length; i++){  
188             colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];  
189             fractions[i] = rand.nextFloat();  
190         }  
191         Arrays.sort(fractions);  
192           
193         g2.setColor(Color.GRAY);// 设置边框色  
194         g2.fillRect(0, 0, w, h);  
195           
196         Color c = getRandColor(200, 250);  
197         g2.setColor(c);// 设置背景色  
198         g2.fillRect(0, 2, w, h-4);  
199           
200         //绘制干扰线  
201         Random random = new Random();  
202         g2.setColor(getRandColor(160, 200));// 设置线条的颜色  
203         for (int i = 0; i < 20; i++) {  
204             int x = random.nextInt(w - 1);  
205             int y = random.nextInt(h - 1);  
206             int xl = random.nextInt(6) + 1;  
207             int yl = random.nextInt(12) + 1;  
208             g2.drawLine(x, y, x + xl + 40, y + yl + 20);  
209         }  
210           
211         // 添加噪点  
212         float yawpRate = 0.05f;// 噪声率  
213         int area = (int) (yawpRate * w * h);  
214         for (int i = 0; i < area; i++) {  
215             int x = random.nextInt(w);  
216             int y = random.nextInt(h);  
217             int rgb = getRandomIntColor();  
218             image.setRGB(x, y, rgb);  
219         }  
220           
221         shear(g2, w, h, c);// 使图片扭曲  
222   
223         g2.setColor(getRandColor(100, 160));  
224         int fontSize = h-4;  
225         Font font = new Font("Algerian", Font.ITALIC, fontSize);  
226         g2.setFont(font);  
227         char[] chars = code.toCharArray();  
228         for(int i = 0; i < verifySize; i++){  
229             AffineTransform affine = new AffineTransform();  
230             affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);  
231             g2.setTransform(affine);  
232             g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);  
233         }  
234           
235         g2.dispose();  
236         ImageIO.write(image, "jpg", os);  
237     }  
238       
239     private static Color getRandColor(int fc, int bc) {  
240         if (fc > 255)  
241             fc = 255;  
242         if (bc > 255)  
243             bc = 255;  
244         int r = fc + random.nextInt(bc - fc);  
245         int g = fc + random.nextInt(bc - fc);  
246         int b = fc + random.nextInt(bc - fc);  
247         return new Color(r, g, b);  
248     }  
249       
250     private static int getRandomIntColor() {  
251         int[] rgb = getRandomRgb();  
252         int color = 0;  
253         for (int c : rgb) {  
254             color = color << 8;  
255             color = color | c;  
256         }  
257         return color;  
258     }  
259       
260     private static int[] getRandomRgb() {  
261         int[] rgb = new int[3];  
262         for (int i = 0; i < 3; i++) {  
263             rgb[i] = random.nextInt(255);  
264         }  
265         return rgb;  
266     }  
267   
268     private static void shear(Graphics g, int w1, int h1, Color color) {  
269         shearX(g, w1, h1, color);  
270         shearY(g, w1, h1, color);  
271     }  
272       
273     private static void shearX(Graphics g, int w1, int h1, Color color) {  
274   
275         int period = random.nextInt(2);  
276   
277         boolean borderGap = true;  
278         int frames = 1;  
279         int phase = random.nextInt(2);  
280   
281         for (int i = 0; i < h1; i++) {  
282             double d = (double) (period >> 1)  
283                     * Math.sin((double) i / (double) period  
284                             + (6.2831853071795862D * (double) phase)  
285                             / (double) frames);  
286             g.copyArea(0, i, w1, 1, (int) d, 0);  
287             if (borderGap) {  
288                 g.setColor(color);  
289                 g.drawLine((int) d, i, 0, i);  
290                 g.drawLine((int) d + w1, i, w1, i);  
291             }  
292         }  
293   
294     }  
295   
296     private static void shearY(Graphics g, int w1, int h1, Color color) {  
297   
298         int period = random.nextInt(40) + 10; // 50;  
299   
300         boolean borderGap = true;  
301         int frames = 20;  
302         int phase = 7;  
303         for (int i = 0; i < w1; i++) {  
304             double d = (double) (period >> 1)  
305                     * Math.sin((double) i / (double) period  
306                             + (6.2831853071795862D * (double) phase)  
307                             / (double) frames);  
308             g.copyArea(i, 0, 1, h1, 0, (int) d);  
309             if (borderGap) {  
310                 g.setColor(color);  
311                 g.drawLine(i, (int) d, i, 0);  
312                 g.drawLine(i, (int) d + h1, i, h1);  
313             }  
314   
315         }  
316   
317     }  
318     public static void main(String[] args) throws IOException{  
319         File dir = new File("F:/verifies");  
320         int w = 200, h = 80;  
321         for(int i = 0; i < 50; i++){  
322             String verifyCode = generateVerifyCode(4);  
323             File file = new File(dir, verifyCode + ".jpg");  
324             outputImage(w, h, file, verifyCode);  
325         }  
326     }  
327     
328    
329 }  

 

5.至此验证码功能已经实现,感谢大神,贴出整个ssm开源项目地址:https://github.com/baichengzhou/SpringMVC-Mybatis-Shiro-redis-0.2

                      我不是代码的生产者我只是代码的搬运工hhhhh

转载于:https://www.cnblogs.com/ztybug/p/9741901.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值