程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java仿12306圖片驗證碼

Java仿12306圖片驗證碼

編輯:關於JAVA

Java仿12306圖片驗證碼。本站提示廣大學習愛好者:(Java仿12306圖片驗證碼)文章只能為提供參考,不一定能成為您想要的結果。以下是Java仿12306圖片驗證碼正文


因為要做一個新項目,所以盤算做一個簡略的圖片驗證碼。

先說說思緒吧:在辦事端,從一個文件夾外面找出8張圖片,再把8張圖片歸並成一張年夜圖,在8個小圖外面隨機生成一個要用戶驗證的圖片分類,如小狗、啤酒等。在前端,拜訪這個頁面時,把圖片加載上去,用戶在圖片上選擇提醒所須要的圖片,當用戶點上岸時,依據用戶選擇的一切坐標斷定所選的圖片是否是現實上的驗證圖片。

先放兩張後果圖:

為了讓文件查找比擬簡略,在圖片文件構造上可以如許:

如許便利生成用戶要選擇的Key圖片,和掏出8張小圖歸並成年夜圖。

上代碼:這是選擇8張圖片,而且在每張圖片拔取時用遞歸包管拔取的圖片不會反復。

//拔取8個圖片
public static List<Object> getEightImages() {
 //保留取到的每個圖片的path,包管圖片不會反復
 List<String> paths = new ArrayList<String>();
  
 File[] finalImages = new File[8];
 List<Object> object = new ArrayList<Object>();
  
 //保留tips
 String[] tips = new String[8];
  
 for (int i = 0; i < 8; i++) {
  //獲得隨機的二級目次
  int dirIndex = getRandom(secondaryDirNumbers);
  File secondaryDir = getFiles()[dirIndex];
   
  //隨機到的文件夾稱號保留到tips中
  tips[i] = secondaryDir.getName();
   
  //獲得二級圖片目次下的文件
  File[] images = secondaryDir.listFiles();
   
  int imageIndex = getRandom(imageRandomIndex);
  File image = images[imageIndex];
   
  //圖片去重
  image = dropSameImage(image, paths, tips, i);  
   
  paths.add(image.getPath());
 
  finalImages[i] = image;
   
 }
 object.add(finalImages);
 object.add(tips);
 return object;
} 

在生成這8張圖片中,用一個數組保留一切的文件分類。在這個分類外面可以用隨機數拔取一個分類做為Key分類,就是用戶要選擇的一切圖片。因為數組是有序的,可以遍歷數組中的元素,獲得每一個key分類圖片的地位,便利在用戶驗證時,停止婚配。

//獲得地位,前往的是第幾個圖片,而不是下標,從1開端,聚集第一個元素為tip
 public static List<Object> getLocation(String[] tips) {
  List<Object> locations = new ArrayList<Object>();
  
  //獲得Key分類
  String tip = getTip(tips);
  locations.add(tip);
   
  int length = tips.length;
  for (int i = 0; i < length; i++) {
   if (tip.equals(tips[i])) {
 
    locations.add(i+1);
   }
  }
  return locations;
 }
 

拔取了8張圖片後,接上去就是歸並圖片。歸並圖片可以用到BufferedImage這個類的辦法:setRGB()這個辦法假如不明確可以看下api文檔,下面有具體的解釋。

public static void mergeImage(File[] finalImages, HttpServletResponse response) throws IOException {
     
  //讀取圖片
  BufferedImage mergeImage = new BufferedImage(800, 400, BufferedImage.TYPE_INT_BGR);
   
  for (int i = 0; i < 8; i++) {
   File image = finalImages[i];
    
   BufferedImage bufferedImage = ImageIO.read(image);
   int width = bufferedImage.getWidth();
   int height = bufferedImage.getHeight();
   //從圖片中讀取RGB
   int[] imageBytes = new int[width*height];
   imageBytes = bufferedImage.getRGB(0, 0, width, height, imageBytes, 0, width);
   if ( i < 4) {
    mergeImage.setRGB(i*200, 0, width, height, imageBytes, 0, width);
   } else {
    mergeImage.setRGB((i -4 )*200, 200, width, height, imageBytes, 0, width);
   }   
    
  }
 
  
  ImageIO.write(mergeImage, "jpg", response.getOutputStream());
  //ImageIO.write(mergeImage, "jpg", destImage);
 }
 

  在controller層中,先把key分類保留到session中,為用戶選擇圖片分類做提醒和圖片驗證做斷定。然後把圖片流輸入到response中,便可以生成驗證圖片了。

response.setContentType("image/jpeg"); 
  response.setHeader("Pragma", "No-cache"); 
  response.setHeader("Cache-Control", "no-cache"); 
  response.setDateHeader("Expires", 0);
  
  List<Object> object = ImageSelectedHelper.getEightImages();
  File[] finalImages = (File[]) object.get(0);
  
  String[] tips = (String[]) object.get(1);
  //一切key的圖片地位,即用戶必需要選的圖片
  List<Object> locations = ImageSelectedHelper.getLocation(tips);
  
  String tip = locations.get(0).toString();
  System.out.println(tip);
  session.setAttribute("tip", tip);
  locations.remove(0);
  
  int length = locations.size();
  for (int i = 0; i < length; i++) {
   System.out.println("現實Key圖片地位:" + locations.get(i));
  }

  session.setAttribute("locations", locations);
  ImageMerge.mergeImage(finalImages, response);

  在jsp中,為用戶的點擊生成小圖片標志。當用戶點圖片擊時,在父div上添加一個子div標簽,而且把他定位為relative, 而且設置zIndex,然後再這個div上添加一個img標簽,定位為absolute。在用戶的點擊時,可以獲得點擊事宜,依據點擊事宜獲得點擊坐標,然後減去父div的坐標,便可以獲得絕對坐標。可以依據本身的愛好定坐標原點,這裡的坐標原點是第8個圖片的右下角。  

<div><br>  <div id="base"><br>   <img src="<%=request.getContextPath()%>/identify"  onclick="clickImg(event)" id="bigPicture"><br>  </div><br>  <br> </div><br><br>function clickImg(e) {
  var baseDiv = document.getElementById("base");
  var topValue = 0;
  var leftValue = 0;
  var obj = baseDiv;
  while (obj) {
   leftValue += obj.offsetLeft;
   topValue +=obj.offsetTop;
   obj = obj.offsetParent;
  }
  //處理firefox獲得不到點擊事宜的成績
  var clickEvent = e ? e : (window.event ? window.event : null);
    
  var clickLeft = clickEvent.clientX + document.body.scrollLeft - document.body.clientLeft - 10;
  var clickTop = clickEvent.clientY + document.body.scrollTop - document.body.clientTop - 10;
  var divId = "img_" + index++;
  
  var divEle = document.createElement("div");
  
  divEle.setAttribute("id", divId);
  divEle.style.position = "relative";
  divEle.style.zIndex = index;
  divEle.style.width = "20px";
  divEle.style.height = "20px";
  divEle.style.display = "inline";
  
  divEle.style.top = clickTop - topValue - 150 + 10 + "px";
  divEle.style.left = clickLeft - leftValue - 300 + "px";
  
  divEle.setAttribute("onclick", "remove('" + divId + "')");
  baseDiv.appendChild(divEle);
  
  var imgEle = document.createElement("img");
  imgEle.src = "<%=request.getContextPath()%>/resources/timo.png";
  imgEle.style.width = "20px";
  imgEle.style.height = "20px";
  imgEle.style.top = "0px";
  imgEle.style.left = "0px";
  imgEle.style.position = "absolute";
  imgEle.style.zIndex = index;
  divEle.appendChild(imgEle);
 }

用戶選擇登錄後,辦事器端依據用戶的選擇坐標停止斷定

public List<Integer> isPass(String result) {
   
  String[] xyLocations = result.split(",");
  //保留用戶選擇的坐標落在哪些圖片上
  List<Integer> list = new ArrayList<Integer>();
  //每組坐標
  System.out.println("用戶選擇圖片數:"+xyLocations.length);
  for (String xyLocation : xyLocations) {
   String[] xy = xyLocation.split("\\|\\|");
   int x = Integer.parseInt(xy[0]);
   int y = Integer.parseInt(xy[1]);
    
   //8,4圖片區間
   if ( x > -75 && x <= 0) {
 
    if ( y > -75 && y <= 0) {  //8號
     list.add(8);
  
    } else if ( y >= -150 && y <= -75 ) {  //4號
     list.add(4);
    }
   } else if ( x > -150 && x <= -75) {  //7,3圖片區間
     
    if ( y > -75 && y <= 0) {  //7號
     list.add(7);
  
    } else if ( y >= -150 && y <= -75 ) {  //3號
     list.add(3);
    }
   } else if ( x > -225 && x <= -150) {  //6,2圖片區間
     
    if ( y > -75 && y <= 0) {  //6號
     list.add(6);
  
    } else if ( y >= -150 && y <= -75 ) {  //2號
     list.add(2);
    }
     
   } else if ( x >= -300 && x <= -225) {  //5,1圖片區間
     
    if ( y > -75 && y <= 0) {  //5號
     list.add(5);
  
    } else if ( y >= -150 && y <= -75 ) {  //1號
     list.add(1);
    }
   } else {
    return null;
   }
  }
  return list;
 }
 

 

刷重生成新的圖片,因為ajax不支撐二進制流,可以本身用原生的xmlHttpRequest對象加html5的blob來完成。

function refresh() {
 var url = "<%=request.getContextPath()%>/identify";
 var xhr = new XMLHttpRequest();
 xhr.open('GET', url, true);
 xhr.responseType = "blob";
 xhr.onload = function() {
  if (this.status == 200) {
   var blob = this.response;    
   //加載勝利後釋放blob
   bigPicture.onload = function(e) {
    window.URL.revokeObjectURL(bigPicture.src);
   };
   bigPicture.src = window.URL.createObjectURL(blob);
  }
 }
 xhr.send();

 驗證碼全體代碼完成了,還有有一些細節要處置。

以上就是本文的全體內容,願望對年夜家的進修有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved