1、生成前端小图片,以及对于大图片加背景颜色

package com.stock.core.util;import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import sun.misc.BASE64Encoder;/*** 随机切割图片工具类** @Author: liuqiaoyue* @Date: 2022-05-13 13:32* @Version 1.0*/
public class RandomCutPicUtils {/*** 背景图的宽、高*/private static final int BG_WIDTH = 590;private static final int BG_HEIGHT = 360;/*** 模板图的宽、高*/private static final int TEMPLATE_WIDTH = 120;private static final int TEMPLATE_HEIGHT = 100;/*** 圆的半径*/private static final int CIRCLE_RADIO = 20;/*** 抠图的边框宽度*/private static int SLIDER_IMG_OUT_PADDING = 1;// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ///*** 获取大图,小图* @param bgPathInputStream 背景图文件* @return* @throws Exception*/public static Map<String, Object> generateTwoImage(InputStream bgPathInputStream) throws Exception {
//   public static Map<String, Object> generateTwoImage(HttpSession session, HttpServletResponse response,  File bgPath) throws Exception {Map<String, Integer> startPoint = getStartPoint();int xBegin = startPoint.get("xBegin");int yBegin = startPoint.get("yBegin");// 抠图轮廓int[][] templateImage = getBlockData();// 原始背景图BufferedImage bgImage = ImageIO.read(bgPathInputStream);// 抠图(空白)BufferedImage blankImage = new BufferedImage(TEMPLATE_WIDTH, TEMPLATE_HEIGHT,BufferedImage.TYPE_4BYTE_ABGR);Graphics2D graphics = blankImage.createGraphics();graphics.setBackground(Color.white);cutByTemplate(bgImage, blankImage, templateImage, xBegin, yBegin);// “抗锯齿”的属性graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);graphics.setStroke(new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));graphics.drawImage(blankImage, 0, 0, null);graphics.dispose();Map<String, Object> resultMap = new HashMap<>();resultMap.put("image", getImageBASE64(bgImage));//大图resultMap.put("image2", getImageBASE64(blankImage)); //小图resultMap.put("xBegin",xBegin);resultMap.put("yBegin", yBegin);return resultMap;}/*** 获取大图,小图Base64码** @param bgPath 背景图路径*/public static Map<String, String> generateTwoImageBase64(String bgPath)throws Exception {Map<String, Integer> startPoint = getStartPoint();int xBegin = startPoint.get("xBegin");int yBegin = startPoint.get("yBegin");// 抠图轮廓int[][] templateImage = getBlockData();// 原始背景图BufferedImage bgImage = ImageIO.read(new FileInputStream(bgPath));// 空白抠图BufferedImage blankImage = new BufferedImage(TEMPLATE_WIDTH, TEMPLATE_HEIGHT,BufferedImage.TYPE_4BYTE_ABGR);cutByTemplate(bgImage, blankImage, templateImage, xBegin, yBegin);Map<String, String> resultMap = new HashMap<>(2);// 大图resultMap.put("big", getImageBASE64(bgImage));// 小图resultMap.put("small", getImageBASE64(blankImage));return resultMap;}/*** 获取切图在背景图中的 开始点*/private static Map<String, Integer> getStartPoint() {Random random = new Random();int xBegin = random.nextInt(BG_WIDTH - 3*TEMPLATE_WIDTH) + 2*TEMPLATE_WIDTH + 5;int yBegin = TEMPLATE_HEIGHT + random.nextInt(BG_HEIGHT - TEMPLATE_HEIGHT * 2);Map<String, Integer> map = new HashMap<>(2);map.put("xBegin", xBegin);map.put("yBegin", yBegin);return map;}/*** 生成随机滑块形状* <p>* 0 透明像素* 1 滑块像素* 2 阴影像素** @return int[][]*/private static int[][] getBlockData() {int[][] data = new int[TEMPLATE_WIDTH][TEMPLATE_HEIGHT];Random random = new Random();//(x-a)²+(y-b)²=r²//x中心位置左右5像素随机double x1 = CIRCLE_RADIO + (TEMPLATE_WIDTH - 2 * CIRCLE_RADIO) / 2.0 - 5 + random.nextInt(10);//y 矩形上边界半径-1像素移动double y1_top = CIRCLE_RADIO - random.nextInt(3);double y1_bottom = TEMPLATE_HEIGHT - CIRCLE_RADIO + random.nextInt(3);double y1 = random.nextInt(2) == 1 ? y1_top : y1_bottom;double x2_right = TEMPLATE_WIDTH - CIRCLE_RADIO - CIRCLE_RADIO + random.nextInt(2 * CIRCLE_RADIO - 4);double x2_left = CIRCLE_RADIO + CIRCLE_RADIO - 2 - random.nextInt(2 * CIRCLE_RADIO - 4);double x2 = random.nextInt(2) == 1 ? x2_right : x2_left;double y2 = CIRCLE_RADIO + (TEMPLATE_HEIGHT - 2 * CIRCLE_RADIO) / 2.0 - 4 + random.nextInt(10);double po = Math.pow(CIRCLE_RADIO, 2);for (int i = 0; i < TEMPLATE_WIDTH; i++) {for (int j = 0; j < TEMPLATE_HEIGHT; j++) {//矩形区域boolean fill;if ((i >= CIRCLE_RADIO && i < TEMPLATE_WIDTH - CIRCLE_RADIO)&& (j >= CIRCLE_RADIO && j < TEMPLATE_HEIGHT - CIRCLE_RADIO)) {data[i][j] = 1;fill = true;} else {data[i][j] = 0;fill = false;}//凸出区域double d3 = Math.pow(i - x1, 2) + Math.pow(j - y1, 2);if (d3 < po) {data[i][j] = 1;} else {if (!fill) {data[i][j] = 0;}}//凹进区域double d4 = Math.pow(i - x2, 2) + Math.pow(j - y2, 2);if (d4 < po) {data[i][j] = 0;}}}//边界阴影for (int i = 0; i < TEMPLATE_WIDTH; i++) {for (int j = 0; j < TEMPLATE_HEIGHT; j++) {//四个正方形边角处理for (int k = 1; k <= SLIDER_IMG_OUT_PADDING; k++) {//左上、右上if (i >= CIRCLE_RADIO - k && i < CIRCLE_RADIO&& ((j >= CIRCLE_RADIO - k && j < CIRCLE_RADIO)|| (j >= TEMPLATE_HEIGHT - CIRCLE_RADIO - k && j < TEMPLATE_HEIGHT - CIRCLE_RADIO + 1))) {data[i][j] = 2;}//左下、右下if (i >= TEMPLATE_WIDTH - CIRCLE_RADIO + k - 1 && i < TEMPLATE_WIDTH - CIRCLE_RADIO + 1) {for (int n = 1; n <= SLIDER_IMG_OUT_PADDING; n++) {if (((j >= CIRCLE_RADIO - n && j < CIRCLE_RADIO)|| (j >= TEMPLATE_HEIGHT - CIRCLE_RADIO - n && j <= TEMPLATE_HEIGHT - CIRCLE_RADIO))) {data[i][j] = 2;}}}}if (data[i][j] == 1 && j - SLIDER_IMG_OUT_PADDING > 0 && data[i][j - SLIDER_IMG_OUT_PADDING] == 0) {data[i][j - SLIDER_IMG_OUT_PADDING] = 2;}//解决凸出圆弧没有上/下边框问题if (data[i][j] == 1 && j + SLIDER_IMG_OUT_PADDING > 0 && j + SLIDER_IMG_OUT_PADDING <= TEMPLATE_HEIGHT) {if (j == 0 || (j+1) == TEMPLATE_HEIGHT){data[i][j] = 2;}else {if (j + SLIDER_IMG_OUT_PADDING < TEMPLATE_HEIGHT && data[i][j + SLIDER_IMG_OUT_PADDING] == 0) {data[i][j + SLIDER_IMG_OUT_PADDING] = 2;}}}if (data[i][j] == 1 && i - SLIDER_IMG_OUT_PADDING > 0 && data[i - SLIDER_IMG_OUT_PADDING][j] == 0) {data[i - SLIDER_IMG_OUT_PADDING][j] = 2;}if (data[i][j] == 1 && i + SLIDER_IMG_OUT_PADDING > 0 && i + SLIDER_IMG_OUT_PADDING < TEMPLATE_WIDTH && data[i + SLIDER_IMG_OUT_PADDING][j] == 0) {data[i + SLIDER_IMG_OUT_PADDING][j] = 2;}}}return data;}/*** 生成小图片、给大图片添加阴影** @param bgImage       背景图* @param blankImage    抠图(空白)* @param templateImage 抠图模板* @param x             抠图开始坐标* @param y             抠图开始坐标*/private static void cutByTemplate(BufferedImage bgImage, BufferedImage blankImage,int[][] templateImage, int x, int y) {for (int i = 0; i < TEMPLATE_WIDTH; i++) {for (int j = 0; j < TEMPLATE_HEIGHT; j++) {int _x = x + i;int _y = y + j;int rgbFlg = templateImage[i][j];int rgb_ori = bgImage.getRGB(_x, _y);// 原图中对应位置变色处理if (rgbFlg == 1) {//抠图上复制对应颜色值blankImage.setRGB(i, j, rgb_ori);//原图对应位置颜色变化bgImage.setRGB(_x, _y, rgb_ori & 0x363636);} else if (rgbFlg == 2) {blankImage.setRGB(i, j, Color.WHITE.getRGB());bgImage.setRGB(_x, _y, Color.GRAY.getRGB());} else if (rgbFlg == 0) {//int alpha = 0;blankImage.setRGB(i, j, rgb_ori & 0x00ffffff);}}}}/*** 获取大图,小图** @param bgPath 背景图路径*/public static Map<String, BufferedImage> generateTwoImage(HttpSession session, HttpServletResponse response, String bgPath) throws Exception {Map<String, Integer> startPoint = getStartPoint();int xBegin = startPoint.get("xBegin");int yBegin = startPoint.get("yBegin");// 抠图轮廓int[][] templateImage = getBlockData();// 原始背景图BufferedImage bgImage = ImageIO.read(new FileInputStream(bgPath));// 抠图(空白)BufferedImage blankImage = new BufferedImage(TEMPLATE_WIDTH, TEMPLATE_HEIGHT,BufferedImage.TYPE_4BYTE_ABGR);cutByTemplate(bgImage, blankImage, templateImage, xBegin, yBegin);Map<String, BufferedImage> resultMap = new HashMap<>(2);//大图resultMap.put("big", bgImage);//小图resultMap.put("small", blankImage);return resultMap;}/*** 图片转BASE64*/private static String getImageBASE64(BufferedImage image) throws IOException {ByteArrayOutputStream out = new ByteArrayOutputStream();ImageIO.write(image, "png", out);//转成byte数组byte[] b = out.toByteArray();BASE64Encoder encoder = new BASE64Encoder();//生成base64编码return encoder.encode(b);}/*** 图片文件输出** @param image     图* @param imagePath 图的输出路径*/public static void outputImageFile(BufferedImage image, String imagePath) throws Exception {ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(image, "png", os);byte[] newImages = os.toByteArray();FileOutputStream fos = new FileOutputStream(imagePath);fos.write(newImages);fos.close();}/*** 图片文件输出** @param image     图* @param imagePath 图的输出路径*/public static void outputImageFile(BufferedImage image, File imagePath) throws Exception {ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(image, "png", os);byte[] newImages = os.toByteArray();FileOutputStream fos = new FileOutputStream(imagePath);fos.write(newImages);fos.close();}}

2、请求地址调用以base64方式传到前端。

最好选择传到文件服务器或者其他更好的方式。两张图片的base64很大,传输比较耗时。其次,如果请求验证码的接口被攻击,base64传输图片的方式会照成服务器瘫痪。

    @PostMapping("/getImg")@ResponseBodypublic JsonResponse<Map<String, Object>> createCodePlus() throws Exception {JsonResponse<Map<String, Object>> responseTemp = new JsonResponse<Map<String, Object>>();Map<String, Object> rtnMap = new HashMap<String, Object>();//随机选择目标图片Random randomImages = new Random();String picPath = "templates/randomImg/" + randomImages.nextInt(20) + ".png";picPath = URLDecoder.decode(picPath,"utf-8");Resource resource = new ClassPathResource(picPath);//获取坐标、大小图片rtnMap = RandomCutPicUtils.generateTwoImage(resource.getInputStream());rtnMap.remove("xBegin");responseTemp.setResult(rtnMap);return responseTemp;
}

滑动图片验证登录-java后端相关推荐

  1. vue中纯前端实现滑动图片验证的方式

    Hello,大家好呀~ 众所周知,滑动图片验证一直是各类网站登录和注册的一种校验方式,是用来防止有人恶意使用脚本批量进行操作从而设置的一种安全保护方式. 一般而言,这种滑动图片验证是可以通过后端配合完 ...

  2. 前端JS——滑动滑块验证登录(源码及效果)

    源码: <!doctype html> <html lang="en"><head><meta charset="UTF-8&q ...

  3. App接入阿里云号码认证服务 一键登录 Java后端服务部分

    下面是后台java部分,通过App端,用户确认授权后拿到的actoken来换取电话号码 Java服务端SDK <dependency><groupId>com.aliyun&l ...

  4. 微信小程序获取手机号登录(Java后端)

    1.添加依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok< ...

  5. vue滑动图片验证的方式

    本篇文章使用的是一款中间件 第一步使用npm安装 npm install --save vue-monoplasty-slide-verify 在main.js中引用 import SlideVeri ...

  6. vue3 滑块拼图验证登录(vue3-puzzle-vcode)

    这里写自定义目录标题 首先,我们项目中很多情况下会用到滑动图片验证登录 vue有一个插件可以满足我们的需求 第一步先安装 npm install vue3-puzzle-vcode --save 第二 ...

  7. WordPress登录注册评论滑动图片验证码插件腾讯云验证码(CAPTCHA)

    为了网站安全我们一般会在登录页.注册页.评论页添加验证码功能,传统的验证码都是输入字母数字或加减法等,现在比较流行图片滑动验证码.最为关键的是腾讯云提供有图形验证(图片滑动验证码)服务器(一年内提供几 ...

  8. 【VUE】vue实现登录滑动拼图验证的两种方法,纯前端组件验证以及前后端同时验证

    vue实现登录滑动拼图验证的两种方法: 第一种是纯前端组件验证,只能区分是人为操作还是机器操作. 第二种是前后端同时验证,这种方法加上后端校验相对会更安全一些.(注:在最底部加上了同时兼容移动端的方法 ...

  9. java 后端 验证码逻辑_Java后端产生验证码后台验证功能的实现代码

    直接跳severlet在java后台生成验证码: @RequestMapping(value="yzm.action") public void Yzm(HttpSession s ...

最新文章

  1. 元宵节来了,程序员用 Python 送你一盏 3D 花灯
  2. curl: (7) couldn‘t connect to host 解决方法
  3. 239 Sliding Window Maximum 滑动窗口最大值
  4. android开发--翻转闹铃(从制作到打包)
  5. @value 静态变量_Spring注解驱动开发之八——@Value属性赋值、@PropertySource 加载外部配置文件...
  6. MyBatisPlus中删除方法deletetById、deleteBatchIds、deleteByMap的使用
  7. sqoop mysql hadoop_使用sqoop将mysql数据导入到hadoop
  8. 计算机队列概念,2020计算机专业考研数据结构知识点:栈、队列和数组
  9. 编程是一门实践性的科学
  10. jpa 多字段like_Spring Date jpa 多个like匹配查询基础问题?
  11. 如何破解受保护的excel密码
  12. 无法嵌入互操作类型NationalInstruments.TestStand.Interop.UI.ExecutionViewOptions。请改用适用的接口...
  13. python template languages_更换Django默认的模板引擎为jinja2的实现方法
  14. 计算机的中mb b单位的关系,b、B、KB、MB、GB 的关系?
  15. HDU 4508 湫湫系列故事――减肥记I 【完全背包】
  16. WideDeep Model、Wide Model(LR)、Deep Model、DeepFm Model、NFM Model复现笔记
  17. bpftrace 段错误 bpf_prog_load_deprecated
  18. 为什么使用计算机辅助翻译工具中文译文,TCloud计算机辅助翻译工具
  19. 晶圆测试Map转换(TSK/TEL/PT301)
  20. spring使用@Primary注解

热门文章

  1. DCIM目录下的.thumbnails文件夹和处理
  2. [深度学习论文笔记][Face Recognition] DeepFace: Closing the Gap to Human-Level Performance in Face Verificati
  3. Python-Pyecharts画图(中国地图,桑葚图,迁移图)[四]
  4. MTK-voice最大音量通话-免提切到耳机模式后音量变小问题总结
  5. Android实现音乐后台播放
  6. 跨国面板数据(1960-2020)三:金融、上市企业、对外援助(stata版)
  7. 《精英的傲慢:好的社会该如何定义成功》笔记与摘录
  8. 调用mstsc命令_远程桌面命令是什么 如何使用命令连接远程桌面
  9. Java配置Path和JAVA_HOME(windows)
  10. TCN 一维预测の笔记