CaptchaUtil2.java 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package com.dashitech.utils;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics;
  5. import java.awt.image.BufferedImage;
  6. import java.util.Random;
  7. public class CaptchaUtil2 {
  8. /**
  9. * 验证码类型为仅数字,即0~9
  10. */
  11. public static final int TYPE_NUM_ONLY = 0;
  12. /**
  13. * 验证码类型为仅字母,即大小写字母混合
  14. */
  15. public static final int TYPE_LETTER_ONLY = 1;
  16. /**
  17. * 验证码类型为数字和大小写字母混合
  18. */
  19. public static final int TYPE_ALL_MIXED = 2;
  20. /**
  21. * 验证码类型为数字和大写字母混合
  22. */
  23. public static final int TYPE_NUM_UPPER = 3;
  24. /**
  25. * 验证码类型为数字和小写字母混合
  26. */
  27. public static final int TYPE_NUM_LOWER = 4;
  28. /**
  29. * 验证码类型为仅大写字母
  30. */
  31. public static final int TYPE_UPPER_ONLY = 5;
  32. /**
  33. * 验证码类型为仅小写字母
  34. */
  35. public static final int TYPE_LOWER_ONLY = 6;
  36. /**
  37. * 生成随机颜色
  38. */
  39. private static Color generateRandomColor() {
  40. Random random = new Random();
  41. return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
  42. }
  43. /**
  44. * 生成图片验证码
  45. *
  46. * @param type
  47. * 验证码类型,参见本类的静态属性
  48. * @param length
  49. * 验证码字符长度,要求大于0的整数
  50. * @param excludeString
  51. * 需排除的特殊字符
  52. * @param width
  53. * 图片宽度(注意此宽度若过小,容易造成验证码文本显示不全,如4个字符的文本可使用85到90的宽度)
  54. * @param height
  55. * 图片高度
  56. * @param interLine
  57. * 图片中干扰线的条数
  58. * @param randomLocation
  59. * 每个字符的高低位置是否随机
  60. * @param backColor
  61. * 图片颜色,若为null则表示采用随机颜色
  62. * @param foreColor
  63. * 字体颜色,若为null则表示采用随机颜色
  64. * @param lineColor
  65. * 干扰线颜色,若为null则表示采用随机颜色
  66. * @return 图片缓存对象
  67. */
  68. public static BufferedImage generateImageCode(int type, int length, String excludeString, int width, int height, int interLine, boolean randomLocation, Color backColor, Color foreColor, Color lineColor) {
  69. String textCode = generateTextCode(type, length, excludeString);
  70. return generateImageCode(textCode, width, height, interLine, randomLocation, backColor, foreColor, lineColor);
  71. }
  72. /**
  73. * 生成验证码字符串
  74. *
  75. * @param type
  76. * 验证码类型,参见本类的静态属性
  77. * @param length
  78. * 验证码长度,要求大于0的整数
  79. * @param excludeString
  80. * 需排除的特殊字符(无需排除则为null)
  81. * @return 验证码字符串
  82. */
  83. public static String generateTextCode(int type, int length, String excludeString) {
  84. if (length <= 0) {
  85. return "";
  86. }
  87. StringBuffer verifyCode = new StringBuffer();
  88. int i = 0;
  89. Random random = new Random();
  90. switch (type) {
  91. case TYPE_NUM_ONLY:
  92. while (i < length) {
  93. int t = random.nextInt(10);
  94. // 排除特殊字符
  95. if (null == excludeString || excludeString.indexOf(t + "") < 0) {
  96. verifyCode.append(t);
  97. i++;
  98. }
  99. }
  100. break;
  101. case TYPE_LETTER_ONLY:
  102. while (i < length) {
  103. int t = random.nextInt(123);
  104. if ((t >= 97 || (t >= 65 && t <= 90)) && (null == excludeString || excludeString.indexOf((char) t) < 0)) {
  105. verifyCode.append((char) t);
  106. i++;
  107. }
  108. }
  109. break;
  110. case TYPE_ALL_MIXED:
  111. while (i < length) {
  112. int t = random.nextInt(123);
  113. if ((t >= 97 || (t >= 65 && t <= 90) || (t >= 48 && t <= 57)) && (null == excludeString || excludeString.indexOf((char) t) < 0)) {
  114. verifyCode.append((char) t);
  115. i++;
  116. }
  117. }
  118. break;
  119. case TYPE_NUM_UPPER:
  120. while (i < length) {
  121. int t = random.nextInt(91);
  122. if ((t >= 65 || (t >= 48 && t <= 57)) && (null == excludeString || excludeString.indexOf((char) t) < 0)) {
  123. verifyCode.append((char) t);
  124. i++;
  125. }
  126. }
  127. break;
  128. case TYPE_NUM_LOWER:
  129. while (i < length) {
  130. int t = random.nextInt(123);
  131. if ((t >= 97 || (t >= 48 && t <= 57)) && (null == excludeString || excludeString.indexOf((char) t) < 0)) {
  132. verifyCode.append((char) t);
  133. i++;
  134. }
  135. }
  136. break;
  137. case TYPE_UPPER_ONLY:
  138. while (i < length) {
  139. int t = random.nextInt(91);
  140. if ((t >= 65) && (null == excludeString || excludeString.indexOf((char) t) < 0)) {
  141. verifyCode.append((char) t);
  142. i++;
  143. }
  144. }
  145. break;
  146. case TYPE_LOWER_ONLY:
  147. while (i < length) {
  148. int t = random.nextInt(123);
  149. if ((t >= 97) && (null == excludeString || excludeString.indexOf((char) t) < 0)) {
  150. verifyCode.append((char) t);
  151. i++;
  152. }
  153. }
  154. break;
  155. }
  156. return verifyCode.toString();
  157. }
  158. /**
  159. * 已有验证码,生成验证码图片
  160. *
  161. * @param textCode
  162. * 文本验证码
  163. * @param width
  164. * 图片宽度(注意此宽度若过小,容易造成验证码文本显示不全,如4个字符的文本可使用85到90的宽度)
  165. * @param height
  166. * 图片高度
  167. * @param interLine
  168. * 图片中干扰线的条数
  169. * @param randomLocation
  170. * 每个字符的高低位置是否随机
  171. * @param backColor
  172. * 图片颜色,若为null则表示采用随机颜色
  173. * @param foreColor
  174. * 字体颜色,若为null则表示采用随机颜色
  175. * @param lineColor
  176. * 干扰线颜色,若为null则表示采用随机颜色
  177. * @return 图片缓存对象
  178. */
  179. public static BufferedImage generateImageCode(String textCode, int width, int height, int interLine, boolean randomLocation, Color backColor, Color foreColor, Color lineColor) {
  180. // 创建内存图像
  181. BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  182. // 获取图形上下文
  183. Graphics graphics = bufferedImage.getGraphics();
  184. // 画背景图
  185. graphics.setColor(null == backColor ? generateRandomColor() : backColor);
  186. graphics.fillRect(0, 0, width, height);
  187. // 画干扰线
  188. Random random = new Random();
  189. if (interLine > 0) {
  190. int x = 0, y = 0, x1 = width, y1 = 0;
  191. for (int i = 0; i < interLine; i++) {
  192. graphics.setColor(null == lineColor ? generateRandomColor() : lineColor);
  193. y = random.nextInt(height);
  194. y1 = random.nextInt(height);
  195. graphics.drawLine(x, y, x1, y1);
  196. }
  197. }
  198. // 字体大小为图片高度的80%
  199. int fsize = (int) (height * 0.8);
  200. int fx = height - fsize;
  201. int fy = fsize;
  202. // 设定字体
  203. graphics.setFont(new Font("Default", Font.PLAIN, fsize));
  204. // 写验证码字符
  205. for (int i = 0; i < textCode.length(); i++) {
  206. fy = randomLocation ? (int) ((Math.random() * 0.3 + 0.6) * height) : fy;
  207. graphics.setColor(null == foreColor ? generateRandomColor() : foreColor);
  208. // 将验证码字符显示到图象中
  209. graphics.drawString(textCode.charAt(i) + "", fx, fy);
  210. fx += fsize * 0.9;
  211. }
  212. graphics.dispose();
  213. return bufferedImage;
  214. }
  215. }