验证码图片生成工具

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

 

转载于:https://www.cnblogs.com/zbdouble/p/9020519.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值