Java 生成验证码

╰+哭是因爲堅強的太久メ 2022-04-10 03:25 428阅读 0赞

需求: 随机生成验证码图片

  1. 1 返回随机生成验证码的字符串
  2. 2 将随机生成验证码保存在图片中

使用到的核心类:

BufferedImage类是Image的一个子类,Image和BufferedImage的主要作用就是将一副图片加载到内存中。

BufferedImage生成的图片在内存里有一个图像缓冲区,利用这个缓冲区我们可以很方便的操作这个图片,通常用来做图片修改操作如大小变换、图片变灰、设置图片透明或不透明等。简单看几个方法:







    • BufferedImage(int width, int height, int imageType)

      构造一个 BufferedImage义的图像类型的一个BufferedImage。 构造器创建图片加载到内存。

ImageIO类包含静态方法来定位 ImageReader 和 ImageWriter ,有的用来控制图像读取过程和控制图像写入过程;有的用来执行格式之间的代码转换等。

ImageIO类可将操作后的内存图片BufferedImage同步到OutputStream中(即写入过程,下面用到它),简单看两个读和写的方法 :




























    • static BufferedImage read(ImageInputStream stream)

      返回 BufferedImage作为供给的解码结果 ImageInputStreamImageReader选自目前登记的那些自动选择。

      static BufferedImage read(InputStream input)

      返回 BufferedImage作为供给的解码结果 InputStreamImageReader选自目前登记的那些自动选择。

      static BufferedImage read(URL input)

      返回 BufferedImage作为供给的解码结果 URLImageReader选自目前登记的那些自动选择。

      static boolean write(RenderedImage im, String formatName, File output)

      使用支持给定格式的任意 ImageWriter写入图像到 File

      static boolean write(RenderedImage im, String formatName, ImageOutputStream output)

      使用支持给定格式的任意 ImageWriter写入图像到 ImageOutputStream

      static boolean write(RenderedImage im, String formatName, OutputStream output)

      使用支持给定格式的任意 ImageWriter写入图像到 OutputStream

demo

  1. import javax.imageio.ImageIO;
  2. import java.awt.*;
  3. import java.awt.image.BufferedImage;
  4. import java.io.File;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.OutputStream;
  8. import java.util.Random;
  9. /**
  10. * 验证码生成图片工具类
  11. */
  12. public class VerificationCodeUtil {
  13. private VerificationCodeUtil (){}
  14. /**
  15. * 生成验证码的范围:a-zA-Z0-9
  16. * 去掉0(数字)和O(拼音)容易混淆的(小写的1和L也可以去掉,大写不用了)
  17. */
  18. private static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
  19. 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9' };
  20. /**
  21. * 随机生成n个验证码的字符串和其图片方法
  22. * 思路:
  23. * 1、根据宽高创建 BufferedImage图片对象
  24. * 2、获取图片对象的画笔对象Graphics
  25. * 3、画笔画入数据(背景色,边框,字体,字体位置,颜色等)
  26. * 4、最后通过ImageIO.write()方法将图片对象写入OutputStream
  27. * @param width - 图片宽度
  28. * @param height - 图片高度
  29. * @param codeCount - 验证码个数
  30. * @param outputStream - 保存验证码图片的文件的输出流
  31. * @param imgFormat - 图片格式(JPG,PNG等)
  32. * @return String - 将随机生成的codeCount个验证码以字符串返回
  33. */
  34. public static String generateVerificationCode(int width, int height, int codeCount,
  35. OutputStream outputStream,String imgFormat) throws IOException {
  36. // 1、根据宽高创建 BufferedImage图片对象
  37. BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  38. // 2、获取图片对象的画笔对象Graphics
  39. Graphics2D graphics = bufferedImage.createGraphics();
  40. // 3、画笔画入数据(背景色,边框,字体,字体位置,颜色等)
  41. // 背景色
  42. graphics.setColor(Color.WHITE);
  43. graphics.fillRect(0, 0, width, height);
  44. //边框颜色
  45. graphics.setColor(Color.BLACK);
  46. graphics.drawRect(0, 0, width-1, height-1);
  47. // 字体
  48. Font font = new Font("Fixedsys", Font.PLAIN, height - 2);
  49. // Font font = new Font("微软雅黑", Font.ROMAN_BASELINE, height - 2);
  50. graphics.setFont(font);
  51. // 添加干扰线:坐标/颜色随机
  52. Random random = new Random();
  53. for (int i = 0; i < (codeCount * 2); i++) {
  54. graphics.setColor(getRandomColor());
  55. graphics.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
  56. }
  57. // 添加噪点:
  58. for(int i = 0;i < (codeCount * 3);i++){
  59. int x = random.nextInt(width);
  60. int y = random.nextInt(height);
  61. graphics.setColor(getRandomColor());
  62. graphics.fillRect(x, y, 2,2);
  63. }
  64. // 画随机数:颜色随机,宽高自定义
  65. StringBuffer randomCode = new StringBuffer();
  66. int charWidth = width / (codeCount + 2);
  67. int charHeight = height - 5;
  68. // 随机产生codeCount个字符的验证码。
  69. for (int i = 0; i < codeCount; i++) {
  70. int x = (i + 1) * charWidth;
  71. String strRandom = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
  72. randomCode.append(strRandom);
  73. graphics.setColor(getRandomColor());
  74. //设置字体旋转角度
  75. int degree = random.nextInt() % 30; //角度小于30度
  76. graphics.rotate(degree * Math.PI / 180, x, 45); //正向旋转
  77. graphics.drawString(strRandom, x, charHeight);
  78. graphics.rotate(-degree * Math.PI / 180, x, 45); //反向旋转
  79. }
  80. // 4、最后通过ImageIO.write()方法将图片对象写入OutputStream
  81. ImageIO.write(bufferedImage,imgFormat,outputStream);
  82. return randomCode.toString();
  83. }
  84. /**
  85. * 随机取色
  86. */
  87. private static Color getRandomColor() {
  88. Random ran = new Random();
  89. Color color = new Color(ran.nextInt(256),ran.nextInt(256), ran.nextInt(256));
  90. return color;
  91. }
  92. public static void main(String[] args) {
  93. String validateCode = null;
  94. String path = "E:/java/123.png";
  95. try {
  96. FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
  97. validateCode = VerificationCodeUtil.generateVerificationCode(200,50,5,fileOutputStream,"PNG" );
  98. } catch (IOException e) {
  99. e.printStackTrace();
  100. }
  101. System.out.println(validateCode); // 74QSI
  102. }
  103. }
  104. ![2019083022591052.png][]

总结:掌握两个核心类

  1. java.awt.Image 是抽象类的子类 java.awt.image.BufferedImage
  2. javax.imageio.ImageIO

对于使用到的其他类可根据API查阅使用,可参考文章:

  1. [BufferedImage类、Image类、Graphics类][BufferedImage_Image_Graphics]
  2. 站在前辈的肩膀上,每天进步一点点

ends ~

发表评论

表情:
评论列表 (有 0 条评论,428人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java生成图片验证

    功能介绍:自定义图片尺寸和字符长度,随机背景颜色和字符颜色,随机字符偏移角度,字符平滑边缘,干扰线,噪点,背景扭曲。 VerifyCodeUtils类,生成图片流,然后不同框