java圖片滑動驗證(登錄驗證)原理與實現(xiàn)方法詳解
本文實例講述了java圖片滑動驗證(登錄驗證)原理與實現(xiàn)方法。分享給大家供大家參考,具體如下:
這是我簡單做出的效果圖,處理300X150px的校驗圖,并把圖片發(fā)到前端,用時50毫秒左右,速度還是非??斓?。

原理:
1.利用java從大圖中隨機摳出一張小圖,并在大圖上給摳出小圖的位置加陰影,然后把這兩張圖片返回給前端;
2.前端獲取圖片,用戶滑動小圖到陰影的位置,獲取小圖滑動的距離,返回給java后臺進(jìn)行校驗;
3.校驗通過,返回校驗通過編號;
4.前端調(diào)登錄接口,把賬號、密碼、和校驗編號傳到Java后臺進(jìn)行登錄。
實現(xiàn):
1.計算需要的小圖輪廓,用二維數(shù)組來表示,二維數(shù)組有兩張值,0和1,其中0表示沒有顏色,1有顏色,如下圖,我要摳圖的輪廓是這樣的:

左邊和下邊有有半圓,這個根據(jù)圓的公式就可以了,代碼示例:
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.根據(jù)計算處理的小圖輪廓,在大圖上摳圖
/**
*
* @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];
// 原圖中對應(yīng)位置變色處理
int rgb_ori = oriImage.getRGB(x + i, y + j);
if (rgb == 1) {
//摳圖上復(fù)制對應(yīng)顏色值
targetImage.setRGB(i, j, rgb_ori);
//原圖對應(yīng)位置顏色變化
oriImage.setRGB(x + i, y + j, rgb_ori & 0x363636 );
}else{
//這里把背景設(shè)為透明
targetImage.setRGB(i, j, rgb_ori & 0x00ffffff);
}
}
}
}
3.把大圖小圖轉(zhuǎn)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: 圖片轉(zhuǎn)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();//轉(zhuǎn)成byte數(shù)組
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(b);//生成base64編碼
}
到此圖片驗證關(guān)鍵代碼完畢。
更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計有所幫助。
相關(guān)文章
Java中的StringTokenizer實現(xiàn)字符串切割詳解
這篇文章主要介紹了Java中的StringTokenizer實現(xiàn)字符串切割詳解,java.util工具包提供了字符串切割的工具類StringTokenizer,Spring等常見框架的字符串工具類(如Spring的StringUtils),需要的朋友可以參考下2024-01-01
spring的事務(wù)傳播屬性REQUIRED_NESTED原理
這篇文章主要介紹了spring的事務(wù)傳播屬性REQUIRED_NESTED原理,在spring中,要想使用事務(wù)中的回滾點,可以使用傳播屬性NESTED,需要的朋友可以參考下2023-05-05
關(guān)于SpringCloud的微服務(wù)結(jié)構(gòu)及微服務(wù)遠(yuǎn)程調(diào)用
Spring Cloud 是一套完整的微服務(wù)解決方案,基于 Spring Boot 框架,準(zhǔn)確的說,它不是一個框架,而是一個大的容器,它將市面上較好的微服務(wù)框架集成進(jìn)來,從而簡化了開發(fā)者的代碼量,需要的朋友可以參考下2023-05-05

