java 超经漂亮验证码

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