分享一个生成验证码的java实例

直接上代码:

  1 import javax.imageio.ImageIO;
  2 import java.awt.*;
  3 import java.awt.image.BufferedImage;
  4 import java.io.IOException;
  5 import java.io.OutputStream;
  6 import java.util.Random;
  7 
  8 /**
  9  * @author kabuqinuo
 10  * @date 2018/7/4 13:25
 11  */
 12 public class CreateImageCode {
 13 
 14     /**
 15      * 图片的宽度
 16      */
 17     private int width = 160;
 18     /**
 19      * 图片的高度
 20      */
 21     private int height = 40;
 22     /**
 23      * 验证码字符个数
 24      */
 25     private int codeCount = 4;
 26     /**
 27      * 验证码干扰线数
 28      */
 29     private int lineCount = 20;
 30     /**
 31      * 验证码
 32      */
 33     private String code = null;
 34 
 35     private BufferedImage buffImg = null;
 36     Random random = new Random();
 37 
 38     public CreateImageCode() {
 39         createImage();
 40     }
 41 
 42     public CreateImageCode(int width, int height) {
 43         this.width = width;
 44         this.height = height;
 45         createImage();
 46     }
 47 
 48     public CreateImageCode(int width, int height, int codeCount) {
 49         this.width = width;
 50         this.height = height;
 51         this.codeCount = codeCount;
 52         createImage();
 53     }
 54 
 55     public CreateImageCode(int width, int height, int codeCount, int lineCount) {
 56         this.width = width;
 57         this.height = height;
 58         this.codeCount = codeCount;
 59         this.lineCount = lineCount;
 60         createImage();
 61     }
 62 
 63 
 64     /**
 65      * 生成图片
 66      */
 67     private void createImage() {
 68         // 字体的宽度
 69         int fontWidth = width / codeCount;
 70         // 字体的高度
 71         int fontHeight = height - 5;
 72         int codeY = height - 8;
 73 
 74         // 图像buffer
 75         buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 76         Graphics g = buffImg.getGraphics();
 77 
 78         // 设置背景色
 79         g.setColor(getRandColor(200, 250));
 80         g.fillRect(0, 0, width, height);
 81 
 82 
 83 
 84         // 设置字体
 85         //Font font1 = getFont(fontHeight);
 86         Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
 87         g.setFont(font);
 88 
 89         // 设置干扰线
 90         for (int i = 0; i < lineCount; i++) {
 91             int xs = random.nextInt(width);
 92             int ys = random.nextInt(height);
 93             int xe = xs + random.nextInt(width);
 94             int ye = ys + random.nextInt(height);
 95             g.setColor(getRandColor(1, 255));
 96             g.drawLine(xs, ys, xe, ye);
 97         }
 98 
 99         // 添加噪点
100         float yawpRate = 0.01f;
101         int area = (int) (yawpRate * width * height);
102         for (int i = 0; i < area; i++) {
103             int x = random.nextInt(width);
104             int y = random.nextInt(height);
105 
106             buffImg.setRGB(x, y, random.nextInt(255));
107         }
108 
109         // 得到随机字符
110         String str1 = randomStr(codeCount);
111         this.code = str1;
112         for (int i = 0; i < codeCount; i++) {
113             String strRand = str1.substring(i, i + 1);
114             g.setColor(getRandColor(1, 255));
115 
116             // a为要画出来的东西,x和y表示要画的东西最左侧字符的基线位于此图形上下文坐标系的 (x, y) 位置处
117             g.drawString(strRand, i*fontWidth+3, codeY);
118         }
119     }
120 
121     /**
122      * 得到随机字符串
123      * @param n
124      * @return
125      */
126     private String randomStr(int n) {
127         String str1 = "ABCDEFGHJKMNOPQRSTUVWXYZabcdefghjkmnopqrstuvwxyz1234567890";
128         String str2 = "";
129         int len = str1.length() - 1;
130         double r;
131         for (int i = 0; i < n; i++) {
132             r = (Math.random()) * len;
133             str2 = str2 + str1.charAt((int) r);
134         }
135         return str2;
136     }
137 
138     /**
139      * 得到随机颜色
140      * @param fc
141      * @param bc
142      * @return
143      */
144     private Color getRandColor(int fc, int bc) {
145         if (fc > 255){
146             fc = 255;
147         }
148         if (bc > 255){
149             bc = 255;
150         }
151         int r = fc + random.nextInt(bc - fc);
152         int g = fc + random.nextInt(bc - fc);
153         int b = fc + random.nextInt(bc - fc);
154         return new Color(r, g, b);
155     }
156 
157     /**
158      * 产生随机字体
159      */
160     private Font getFont(int size) {
161         Random random = new Random();
162         Font[] font = new Font[5];
163         font[0] = new Font("Ravie", Font.PLAIN, size);
164         font[1] = new Font("Antique Olive Compact", Font.PLAIN, size);
165         font[2] = new Font("Fixedsys", Font.PLAIN, size);
166         font[3] = new Font("Wide Latin", Font.PLAIN, size);
167         font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, size);
168         return font[random.nextInt(5)];
169     }
170 
171     /**
172      * 扭曲方法
173      * @param g
174      * @param w1
175      * @param h1
176      * @param color
177      */
178     private void shear(Graphics g, int w1, int h1, Color color) {
179         shearX(g, w1, h1, color);
180         shearY(g, w1, h1, color);
181     }
182 
183     private void shearX(Graphics g, int w1, int h1, Color color) {
184 
185         int period = random.nextInt(2);
186 
187         boolean borderGap = true;
188         int frames = 1;
189         int phase = random.nextInt(2);
190 
191         for (int i = 0; i < h1; i++) {
192             double d = (double) (period >> 1)
193                     * Math.sin((double) i / (double) period
194                     + (6.2831853071795862D * (double) phase)
195                     / (double) frames);
196             g.copyArea(0, i, w1, 1, (int) d, 0);
197             if (borderGap) {
198                 g.setColor(color);
199                 g.drawLine((int) d, i, 0, i);
200                 g.drawLine((int) d + w1, i, w1, i);
201             }
202         }
203 
204     }
205 
206     private void shearY(Graphics g, int w1, int h1, Color color) {
207 
208         int period = random.nextInt(40) + 10;
209 
210         boolean borderGap = true;
211         int frames = 20;
212         int phase = 7;
213         for (int i = 0; i < w1; i++) {
214             double d = (double) (period >> 1)
215                     * Math.sin((double) i / (double) period
216                     + (6.2831853071795862D * (double) phase)
217                     / (double) frames);
218             g.copyArea(i, 0, 1, h1, 0, (int) d);
219             if (borderGap) {
220                 g.setColor(color);
221                 g.drawLine(i, (int) d, i, 0);
222                 g.drawLine(i, (int) d + h1, i, h1);
223             }
224 
225         }
226 
227     }
228 
229 
230 
231     public void write(OutputStream sos) throws IOException {
232         ImageIO.write(buffImg, "png", sos);
233         sos.close();
234     }
235 
236     public BufferedImage getBuffImg() {
237         return buffImg;
238     }
239 
240     public String getCode() {
241         return code.toLowerCase();
242     }
243 }

然后是调用方法:

 1 /*生成验证码*/
 2     @ApiOperation(value = "生成验证码", notes = "登录时生成的验证码")
 3     @GetMapping(value = "/code")
 4     public void Captcha(HttpServletResponse response, HttpSession session) throws IOException {
 5 
 6         /*通知浏览器不要缓存*/
 7         response.setHeader("Expires", "-1");
 8         response.setHeader("Cache-Control", "no-cache");
 9         response.setHeader("Pragma", "-1");
10         CreateImageCode vCode = new CreateImageCode(116,36,5,10);
11         String code = vCode.getCode();
12         session.setAttribute("code", code);
13         vCode.write(response.getOutputStream());
14     }

最后是生成的验证码:

直接拿来用即可。

posted @ 2018-12-03 08:29  {{unidentified}}  阅读(571)  评论(0编辑  收藏  举报