实现图片验证码(拖拉验证),包括前后端源码。
限定尝试拖拽4次,尝试4次不成功,将原图片将失效,需重新生成新图片(点击刷新按钮)。
项目只需配置Redis地址就可以。
运行项目后,直接访问地址:http://localhost:8888/index.html 。
滑动图片带描边,适配后,将去掉描边。
源码见: https://github.com/37412449/picture-verification-code
主要功能文件为:src\main\java\com\verification\code\util\VerifyImageUtil.java
如实现抠图、描边等主要功能函数为:
private static byte[] dealOriPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage, int x, int y) throws Exception { // 源文件备份图像矩阵 支持alpha通道的rgb图像 BufferedImage oriCopyImage = new BufferedImage(oriImage.getWidth(), oriImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); // 源文件图像矩阵 int[][] oriImageData = getData(oriImage); // 模板图像矩阵 int[][] templateImageData = getData(templateImage); //copy 源图做不透明处理 for (int i = 0; i < oriImageData.length; i++) { for (int j = 0; j < oriImageData[0].length; j++) { int rgb = oriImage.getRGB(i, j); int r = (0xff & rgb); int g = (0xff & (rgb >> 8)); int b = (0xff & (rgb >> 16)); //无透明处理 rgb = r + (g << 8) + (b << 16) + (255 << 24); oriCopyImage.setRGB(i, j, rgb); } } for (int i = 0; i < templateImageData.length; i++) { for (int j = 0; j < templateImageData[0].length - 5; j++) { int rgb = templateImage.getRGB(i, j); //对源文件备份图像(x+i,y+j)坐标点进行透明处理 if (rgb <= 0) { /* // 注销被扣掉图片位置透明处理,改为直接设置为制定颜色 int rgb_ori = oriCopyImage.getRGB(x + i, y + j); int r = (0xff & rgb_ori); int g = (0xff & (rgb_ori >> 8)); int b = (0xff & (rgb_ori >> 16)); rgb_ori = r + (g << 8) + (b << 16) + (150 << 24); oriCopyImage.setRGB(x + i, y + j, rgb_ori); */ oriCopyImage.setRGB(x + i, y + j, MAT_BG_COLOR.getRGB()); } } }
private static BufferedImage dealCutPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage, BufferedImage targetImage) { // 源文件图像矩阵 int[][] oriImageData = getData(oriImage); // 模板图像矩阵 int[][] templateImageData = getData(templateImage); // 描边 Color lineColor = new Color(250, 149, 47); boolean leftFlag, rightFlag, upFlag, downFlag; _linePoint.clear(); // 模板图像宽度 for (int i = 0; i < templateImageData.length; i++) { // 模板图片高度 for (int j = 0; j < templateImageData[0].length; j++) { leftFlag = rightFlag = upFlag = downFlag = false; // 如果模板图像当前像素点不是白色 copy源文件信息到目标图片中 int rgb = templateImageData[i][j]; if (rgb > 0) { continue; } // 如果是最边上有点,直接描边 if (i == 0 || j == 0 || i == templateImageData.length - 1 || j == templateImageData[0].length - 1) { targetImage.setRGB(i, j, lineColor.getRGB()); continue; } // 上判断[i][j+1] if (j < templateImageData[i].length - 1) { if (templateImageData[i][j + 1] < 0) { upFlag = true; } } // 下判断 [i][j-1] if (templateImageData[i][j - 1] < 0) { downFlag = true; } // 左判断[i-1][j] if (templateImageData[i - 1][j] < 0) { leftFlag = true; } // 右判断[i+1][j] if (i < templateImageData.length - 1) { if (templateImageData[i + 1][j] < 0) { rightFlag = true; } } if (!(leftFlag && rightFlag && upFlag && downFlag)) { targetImage.setRGB(i, j, lineColor.getRGB()); _linePoint.add(new int[]{i, j, oriImageData[i][j]}); } else { targetImage.setRGB(i, j, oriImageData[i][j]); } } } return targetImage; }
具体效果见下图:
本文含有隐藏内容,请 开通VIP 后查看