자바 이미지 슬라이딩 검증 실현(전단 코드 포함)

18505 단어 자바검증 하 다.
머리말
1.다음은 효과 전시 입 니 다.
2.먼저 불평 을 하 겠 습 니 다.블 로그 에서 의 표절 이 정말 심각 합 니 다.그림 미끄럼 검증 을 실현 하기 위해 저 는 오랫동안 자 료 를 검 색 했 지만 내용 이 뒤 집 히 는 것 은 똑 같은 내용 입 니 다.천편일률 적 으로 작 가 는 각각 다 릅 니 다.내용 이 같 으 면 더 이상 말 하지 않 겠 습 니 다.문 제 를 해결 할 수 있 으 면 되 지만 반대로 이런 것들 은 저 에 게 실질 적 으로 문 제 를 해결 해 주지 않 았 습 니 다.사진 검증 은 앞 뒤 가 동시에 상호작용 을 해 야 하 는 기능 일 수도 있 습 니 다.취업 하 는 사람들 은 대부분이 백 스테이지 에 치 우 치 거나 프런트 에 치 우 치기 때문에 쓴 블 로 그 는 전체 절 차 를 완전 하 게 논술 하지 못 합 니 다.다음은 제 가 실천 하여 완성 한 내용 입 니 다.기록 을 해서 여러분 들 이 참고 할 수 있 도록 하 겠 습 니 다.
주:사용 한 컨트롤 과 도구 가 많 기 때문에 생략 한 곳 이 많 습 니 다.여 기 는 핵심 절차 의 기록 만 합 니 다.

1.백 엔 드 이미지 재단 및 생 성
먼저 이미지 처리 도구 인 Verify ImageUtil.class 입 니 다.주요 한 역할 은 두 장의 그림 을 만 드 는 것 입 니 다.하 나 는 일부 원본 그림 을 제외 합 니 다.한 장의 그림 을 파내다.두 가 지 를 결합 하면 완전한 그림 을 구성 할 수 있다.원본 그림(target 디 렉 터 리)은 20 장 을 제공 하고 규격 은 모두 590*360 입 니 다.그림 을 파 는 데 필요 한 템 플 릿 그림(template 디 렉 터 리)은 4 장 이 고 규격 은 모두 93*360(그림 등 각종 자원 은 문 말 에 제 시 됩 니 다)입 니 다.그림 자원 을 우리 프로젝트 의 정적 자원 경로 로 가 져 옵 니 다.(다른 방식 으로 저장 할 수도 있 습 니 다.)제 쪽 은 Spring Boot 프로젝트 이기 때문에 resource 아래 static 디 렉 터 리 에 두 었 습 니 다.

다음은 VerifyImageUtil.class

package com.mine.risk.util;
 
import org.apache.commons.lang.StringUtils;
 
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
 
/**
 *        
 * @author : spirit
 * @date : Created in 10:57 2019/9/05
 */
public class VerifyImageUtil {
 
 /**       */
 private static final int ORI_WIDTH = 590;
 /**       */
 private static final int ORI_HEIGHT = 360;
  /**     x */
 private static int X;
  /**     y */
 private static int Y;
  /**       */
 private static int WIDTH;
  /**       */
 private static int HEIGHT;
 
 public static int getX() {
  return X;
 }
 
 public static int getY() {
  return Y;
 }
 
 /**
  *       
  * @param templateFile     
  * @param targetFile     
  * @param templateType       
  * @param targetType       
  * @return   map  
  * @throws Exception   
  */
 public static Map<String, byte[]> pictureTemplatesCut(File templateFile, File targetFile, String templateType, String targetType) throws Exception {
  Map<String, byte[]> pictureMap = new HashMap<>(2);
  if (StringUtils.isEmpty(templateType) || StringUtils.isEmpty(targetType)) {
   throw new RuntimeException("file type is empty");
  }
  InputStream targetIs = new FileInputStream(targetFile);
  //    
  BufferedImage imageTemplate = ImageIO.read(templateFile);
  WIDTH = imageTemplate.getWidth();
  HEIGHT = imageTemplate.getHeight();
  //         
  generateCutoutCoordinates();
  //     
  BufferedImage newImage = new BufferedImage(WIDTH, HEIGHT, imageTemplate.getType());
  Graphics2D graphics = newImage.createGraphics();
  graphics.setBackground(Color.white);
 
  int bold = 5;
  //           
  BufferedImage targetImageNoDeal = getTargetArea(X, Y, WIDTH, HEIGHT, targetIs, targetType);
 
  //         
  newImage = dealCutPictureByTemplate(targetImageNoDeal, imageTemplate, newImage);
 
  //   “   ”   
  graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  graphics.setStroke(new BasicStroke(bold, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
  graphics.drawImage(newImage, 0, 0, null);
  graphics.dispose();
 
  //   。
  ByteArrayOutputStream os = new ByteArrayOutputStream();
  //  ImageIO    write  , bi png          。
  ImageIO.write(newImage, "png", os);
  byte[] newImages = os.toByteArray();
  pictureMap.put("newImage", newImages);
 
  //       
  BufferedImage oriImage = ImageIO.read(targetFile);
  byte[] oriCopyImages = dealOriPictureByTemplate(oriImage, imageTemplate, X, Y);
  pictureMap.put("oriCopyImage", oriCopyImages);
  System.out.println("X="+X+";y="+Y);
  return pictureMap;
 }
 
 /**
  *        
  * @param oriImage     
  * @param templateImage     
  * @param x   X
  * @param y   Y
  * @return            
  * @throws Exception   
  */
 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 != 16777215 && 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);
    } else {
     //do nothing
    }
   }
  }
  //   
  ByteArrayOutputStream os = new ByteArrayOutputStream();
  //  ImageIO    write  , bi png          
  ImageIO.write(oriCopyImage, "png", os);
  //         
  return os.toByteArray();
 }
 
 
 /**
  *         
  * @param oriImage     
  * @param templateImage     
  * @return            
  */
 private static BufferedImage dealCutPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage,
               BufferedImage targetImage) throws Exception {
  //        
  int[][] oriImageData = getData(oriImage);
  //       
  int[][] templateImageData = getData(templateImage);
  //       
 
  for (int i = 0; i < templateImageData.length; i++) {
   //       
   for (int j = 0; j < templateImageData[0].length; j++) {
    //                 copy           
    int rgb = templateImageData[i][j];
    if (rgb != 16777215 && rgb <= 0) {
     targetImage.setRGB(i, j, oriImageData[i][j]);
    }
   }
  }
  return targetImage;
 }
 
 /**
  *       
  * @param x         x   
  * @param y         y   
  * @param targetWidth        
  * @param targetHeight        
  * @param ois         
  * @return       
  * @throws Exception   
  */
 private static BufferedImage getTargetArea(int x, int y, int targetWidth, int targetHeight, InputStream ois,
            String fileType) throws Exception {
  Iterator<ImageReader> imageReaderList = ImageIO.getImageReadersByFormatName(fileType);
  ImageReader imageReader = imageReaderList.next();
  //      
  ImageInputStream iis = ImageIO.createImageInputStream(ois);
  //               
  imageReader.setInput(iis, true);
 
  ImageReadParam param = imageReader.getDefaultReadParam();
  Rectangle rec = new Rectangle(x, y, targetWidth, targetHeight);
  param.setSourceRegion(rec);
  return imageReader.read(0, param);
 }
 
 /**
  *       
  * @param bufferedImage    
  * @return     
  */
 private static int[][] getData(BufferedImage bufferedImage){
  int[][] data = new int[bufferedImage.getWidth()][bufferedImage.getHeight()];
  for (int i = 0; i < bufferedImage.getWidth(); i++) {
   for (int j = 0; j < bufferedImage.getHeight(); j++) {
    data[i][j] = bufferedImage.getRGB(i, j);
   }
  }
  return data;
 }
 
 /**
  *         
  */
 private static void generateCutoutCoordinates() {
  Random random = new Random();
  // ORI_WIDTH:590 ORI_HEIGHT:360
  // WIDTH:93 HEIGHT:360
  int widthDifference = ORI_WIDTH - WIDTH;
  int heightDifference = ORI_HEIGHT - HEIGHT;
 
  if (widthDifference <= 0) {
   X = 5;
  } else {
   X = random.nextInt(ORI_WIDTH - 3*WIDTH) + 2*WIDTH + 5;
  }
 
  if (heightDifference <= 0) {
   Y = 5;
  } else {
   Y = random.nextInt(ORI_HEIGHT - HEIGHT) + 5;
  }
 
  NumberFormat numberFormat = NumberFormat.getInstance();
  numberFormat.setMaximumFractionDigits(2);
 }
}
도구 류 가 있 으 면 그림 내용 을 만 들 수 있 습 니 다.제 가 있 는 곳 은 Spring 컨트롤 러 에서 내용 을 만 들 고 돌아 갑 니 다.

@RequestMapping("createImgValidate")
@ResponseBody
 public Message createImgValidate(SmsVerificationCodeVo vo){
  try {
   Integer templateNum = new Random().nextInt(4) + 1;
   Integer targetNum = new Random().nextInt(20) + 1;
   File templateFile = ResourceUtils.getFile("classpath:static/images/validate/template/"+templateNum+".png");
   File targetFile = ResourceUtils.getFile("classpath:static/images/validate/target/"+targetNum+".jpg");
   Map<String, byte[]> pictureMap = VerifyImageUtil.pictureTemplatesCut(templateFile, targetFile,
     ConstString.IMAGE_TYPE_PNG,ConstString.IMAGE_TYPE_JPG);
   //              redis 
   String key = ConstString.WEB_VALID_IMAGE_PREFIX + vo.getTelephone();
   boolean verified = redisUtil.exists(key);
   if(verified){
    redisUtil.del(key);
   }
   redisUtil.set(key,(VerifyImageUtil.getX()+67)+"",SmsUtil.VALID_IMAGE_TIMEOUT);
   return ResponseUtil.success(pictureMap);
  } catch (Exception e) {
   e.printStackTrace();
   return ResponseUtil.info(ResponseEnum.BUSINESS_ERROR);
  }
 }
기본 적 인 논 리 는 정적 자원 에서 target 그림 과 template 그림 을 무 작위 로 불 러 와 그림 처리 도구 에 넣 고 우리 가 필요 로 하 는 두 장의 그림 을 처리 하고 되 돌려 주 는 것 입 니 다.그림 을 만 든 후에 이 맵 으로 바로 돌아 갈 수 있 습 니 다.base 64 방식 으로 브 라 우 저 로 돌아 갑 니 다.여기 서 위치 정 보 는 민감 한 내용 에 속 합 니 다.프론트 데스크 에 들 어 오 는 오프셋 비교 검사 에 참여 할 것 입 니 다.그래서 저 는 redis 에 저 장 했 습 니 다.돌아 오 는 내용 은 바로 Map 입 니 다.다만 저 는 사용자 정의 되 돌아 오 는 보조 방법 을 사 용 했 습 니 다.(관심 이 있 는 사람 도 저 에 게 이 보조 도 구 를 찾 을 수 있 습 니 다)
2.전단 전시 사진
우선 Spring Boot 에 대응 하 는 컨트롤 러 에 보 기 를 만 드 는 코드 를 추가 해 야 합 니 다.

/**
  *          
  * @return       
 */
 @RequestMapping("imgValidate")
 public String toImgValidate(ModelMap map, String telephone){
  map.addAttribute("telephone",telephone);
  return "component/imageValidate";
 }
그 다음은 우리 의 HTML 페이지 코드:imageValidate.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>    </title>
 <link rel="stylesheet" type="text/css" th:href="@{/static/css/bootstrap.min.css}" />
 <link rel="stylesheet" type="text/css" th:href="@{/static/fontawesome/css/all.css}" />
 <link rel="stylesheet" type="text/css" th:href="@{/static/css/public.css}" />
 <link rel="stylesheet" type="text/css" th:href="@{/static/css/component/imageValidate.css}" />
</head>
<body>
 <div id="container">
  <div class="imageDiv">
   <img id="validateImage" src=""/>
   <img id="slideImage" src=""/>
  </div>
  <div class="resultDiv">
   <button class="btn btn-success" onclick="exchange();"><i class="fas fa-redo"></i>&nbsp;   </button>
   <span id="operateResult"></span>
  </div>
  <div>
   <div id="sliderOuter">
    <div id="dragDiv">        </div>
    <div id="sliderInner">
     <i class="fas fa-angle-double-right"></i>
     <div class="coverIcon"></div>
    </div>
   </div>
  </div>
 </div>
 
</body>
<script th:inline="javascript">
 var telephone = [[${telephone}]];
</script>
<script type="text/javascript" th:src="@{/static/js/jquery-3.4.0.min.js}" ></script>
<script type="text/javascript" th:src="@{/static/js/component/imageValidate.js}" ></script>
</html>
그 다음 에 대응 하 는 JS 논리 코드:imageValidate.js.전에 말 했 듯 이 배경 에서 돌아 오 는 그림 은 base 64 로 바 뀌 었 기 때문에 그림 을 만 들 때 img 태그 의 src 내용 전에 data:image/png 를 직접 추가 합 니 다.base 64,가능 합 니 다.또 하나의 영어 쉼표 에 주의 하 세 요.

var left = 0;
 
$(function(){
 //         
 initImageValidate();
 
 /*           */
 //       
 $("#sliderInner").mousedown(function(){
  //       
  document.onmousemove = function(ev) {
   left = ev.clientX;
   if(left >= 67 && left <= 563){
    $("#sliderInner").css("left",(left-67)+"px");
    $("#slideImage").css("left",(left-67)+"px");
   }
  };
  //       
  document.onmouseup=function(){
   document.onmousemove=null;
   checkImageValidate();
  };
 });
 
});
 
function initImageValidate(){
 $.ajax({
  async : false,
  type : "POST",
  url : "/common/createImgValidate",
  dataType: "json",
  data:{
   telephone:telephone
  },
  success : function(data) {
   if(data.status < 400){
    //      src  
    $("#validateImage").attr("src", "data:image/png;base64,"+data.data.oriCopyImage);
    $("#slideImage").attr("src", "data:image/png;base64,"+data.data.newImage);
   }else{
    layer.open({
     icon:2,
     title: "    ",
     content: data.info
    });
   }
  },
  error : function() {}
 });
}
 
function exchange(){
 initImageValidate();
}
 
//   
function checkImageValidate(){
 $.ajax({
  async : false,
  type : "POST",
  url : "/common/checkImgValidate",
  dataType: "json",
  data:{
   telephone:telephone,
   offsetHorizontal:left
  },
  success : function(data) {
   if(data.status < 400){
    $("#operateResult").html(data.info).css("color","#28a745");
    //     ,         
    parent.getValidateCode(left);
   }else{
    $("#operateResult").html(data.info).css("color","#dc3545");
    //      ,            
    $("#sliderInner").animate({"left":"0px"},200);
    $("#slideImage").animate({"left":"0px"},200);
   }
  },
  error : function() {}
 });
}
마지막 으로 css 스타일 코드:imageValidate.css

body{
 overflow: hidden;
}
#container{
 width: 100%;
}
.fontDiv{
 margin: 16px 0;
}
.dragFont{
 font-size: 16px;
 color: dodgerblue;
}
.imageDiv{
 width: 590px;
 height: 360px;
 margin: 20px auto 0 auto;
 position: relative;
}
.resultDiv{
 margin: 10px 20px;
}
#validateImage{
 border-radius: 4px;
}
#slideImage{
 position: absolute;
 top: 5px;
 left: 0;
}
#sliderOuter{
 width: 590px;
 height: 40px;
 margin: 12px auto;
 border-radius: 20px;
 box-shadow: 0 0 10px 5px darkgrey;
 display: flex;
 align-items: center;
 justify-content: center;
 position: relative;
}
#dragDiv{
 width: 100%;
 height: 40px;
 position: absolute;
 font-size: 16px;
 color: dodgerblue;
 text-align: center;
 line-height: 40px;
 -webkit-user-select: none;
 -moz-user-select: none;
 -ms-user-select: none;
 user-select: none;
}
#sliderInner{
 width: 94px;
 height: 40px;
 border-radius: 20px;
 font-size: 2rem;
 background-color: #28a745;
 cursor: pointer;
 position: absolute;
 left: 0;
}
#sliderInner i{
 position: relative;
 top: -2px;
 left: 36px;
 color: white;
}
.coverIcon{
 width: 100%;
 height: 100%;
 position: absolute;
 top: 0;
}
리 소스 패키지 다운로드:자바 이미지 슬라이딩 검증
인증 코드 에 관 한 더 많은 글 은 클릭 하여 보 세 요《자바 인증 코드》
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기