java图片滑动验证(登录验证)原理与实现方法详解
本文实例讲述了java图片滑动验证(登录验证)原理与实现方法。分享给大家供大家参考,具体如下:
这是我简单做出的效果图,处理300X150px的校验图,并把图片发到前端,用时50毫秒左右,速度还是非常快的。
原理:
1.利用java从大图中随机抠出一张小图,并在大图上给抠出小图的位置加阴影,然后把这两张图片返回给前端;
2.前端获取图片,用户滑动小图到阴影的位置,获取小图滑动的距离,返回给java后台进行校验;
3.校验通过,返回校验通过编号;
4.前端调登录接口,把账号、密码、和校验编号传到Java后台进行登录。
实现:
1.计算需要的小图轮廓,用二维数组来表示,二维数组有两张值,0和1,其中0表示没有颜色,1有颜色,如下图,我要抠图的轮廓是这样的:
左边和下边有有半圆,这个根据圆的公式就可以了,代码示例:
static int targetLength=55;//小图长 static int targetWidth=45;//小图宽 static int circleR=6;//半径 static int r1=3;//距离点 /** * * @Createdate: 2019年1月24日上午10:52:42 * @Title: getBlockData * @Description: 生成小图轮廓 * @author mzl * @return int[][] * @throws */ private static int[][] getBlockData() { int[][] data = new int[targetLength][targetWidth]; double x2 = targetLength-circleR; //随机生成圆的位置 double h1 = circleR + Math.random() * (targetWidth-3*circleR-r1); double po = circleR*circleR; double xbegin = targetLength-circleR-r1; double ybegin = targetWidth-circleR-r1; for (int i = 0; i < targetLength; i++) { for (int j = 0; j < targetWidth; j++) { double d3 = Math.pow(i - x2,2) + Math.pow(j - h1,2); double d2 = Math.pow(j-2,2) + Math.pow(i - h1,2); if ((j <= ybegin && d2 <= po)||(i >= xbegin && d3 >= po)) { data[i][j] = 0; } else { data[i][j] = 1; } } } return data; }
2.根据计算处理的小图轮廓,在大图上抠图
/** * * @Createdate: 2019年1月24日上午10:51:30 * @Title: cutByTemplate * @Description: 生成小图片、给大图片添加阴影 * @author mzl * @param oriImage * @param targetImage * @param templateImage * @param x * @param y void * @throws */ private static void cutByTemplate(BufferedImage oriImage,BufferedImage targetImage, int[][] templateImage, int x,int y){ for (int i = 0; i < targetLength; i++) { for (int j = 0; j < targetWidth; j++) { int rgb = templateImage[i][j]; // 原图中对应位置变色处理 int rgb_ori = oriImage.getRGB(x + i, y + j); if (rgb == 1) { //抠图上复制对应颜色值 targetImage.setRGB(i, j, rgb_ori); //原图对应位置颜色变化 oriImage.setRGB(x + i, y + j, rgb_ori & 0x363636 ); }else{ //这里把背景设为透明 targetImage.setRGB(i, j, rgb_ori & 0x00ffffff); } } } }
3.把大图小图转base64码,方便返回给前端
/** * * @Createdate: 2019年1月24日上午11:49:42 * @Title: createImage * @Description: 获取大图,小图Base64码 * @author mzl * @param url * @return Map<String,String> * @throws */ public static Map<String,String> createImage(String url,int L,int W,Map<String,String> resultMap){ try { BufferedImage bufferedImage = ImageIO.read(new FileInputStream(url)); BufferedImage target= new BufferedImage(targetLength, targetWidth, BufferedImage.TYPE_4BYTE_ABGR); cutByTemplate(bufferedImage,target,getBlockData(),L,W); resultMap.put("b", getImageBASE64(bufferedImage));//大图 resultMap.put("s", getImageBASE64(target));//小图 } catch (IOException e) { e.printStackTrace(); }finally{ return resultMap; } } /** * * @Createdate: 2019年1月24日上午11:14:19 * @Title: getImageStr * @Description: 图片转BASE64 * @author mzl * @param image * @return * @throws IOException String * @throws */ public static String getImageBASE64(BufferedImage image) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write(image,"png",out); byte[] b = out.toByteArray();//转成byte数组 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(b);//生成base64编码 }
到此图片验证关键代码完毕。
更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
赞 (0)