java实现点击图片文字验证码

Posted 起个名字好难

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java实现点击图片文字验证码相关的知识,希望对你有一定的参考价值。

原文:http://blog.csdn.net/qq_26680031/article/details/51168527

 

 

效果图如上,技术分享

package cn.gdin.captcha;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JcaptchaServlet extends HttpServlet {
    Random random = new Random();
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        int height = 220;  //图片高
        int width = 220;  //图片宽
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics2D g =  (Graphics2D) image.getGraphics();
        String picPath= JcaptchaServlet.class.getClassLoader().getResource("../image/"+(random.nextInt(4)+1)+".jpg").getPath();  读取本地图片,做背景图片
   
        
        g.drawImage(ImageIO.read(new File(picPath)), 0, 20, width, height, null); //将背景图片从高度20开始
        
   
        g.setColor(Color.white);  //设置颜色
        g.drawRect(0, 0, width-1, height-1); //画边框
    
        g.setFont(new Font("宋体",Font.BOLD,20)); //设置字体
        Integer x=null,y=null;  //用于记录坐标
        String target=null; // 用于记录文字
        for(int i=0;i<4;i++){  //随机产生4个文字,坐标,颜色都不同
            g.setColor(new Color(random.nextInt(50)+200, random.nextInt(150)+100, random.nextInt(50)+200));
            String str=getRandomChineseChar();
            int a=random.nextInt(width-100)+50;
            int b=random.nextInt(height-70)+55;
            if(x==null){
                x=a; //记录第一个x坐标
            }
            if(y==null){
                y=b;//记录第一个y坐标
            }
            if(target==null){
                target=str; //记录第一个文字
            }
            g.drawString(str, a, b);
        }
        g.setColor(Color.white);  
        g.drawString("点击"+target, 0,20);//写入验证码第一行文字  “点击..”
        request.getSession().setAttribute("gap",x+":"+y);//将坐标放入session
        //5.释放资源
        g.dispose();
        //6.利用ImageIO进行输出
        ImageIO.write(image, "jpg", response.getOutputStream()); //将图片输出
    
    }
    //网上找的,随机产生汉字的方法
    public  String getRandomChineseChar()
    {
              String str = null;
              int hs, ls; 
              Random random = new Random();
              hs = (176 + Math.abs(random.nextInt(39))); 
              ls = (161 + Math.abs(random.nextInt(93)));
              byte[] b = new byte[2];
              b[0] = (new Integer(hs).byteValue());
              b[1] = (new Integer(ls).byteValue());
              try
              {
                  str = new String(b, "GBk"); //转成中文
              }
              catch (UnsupportedEncodingException ex)
              {
                  ex.printStackTrace();
              }
              return str;
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

前端代码

<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">

$(function(){
    $("#image").click(function(event){
            var obj=this;
           var x=event.offsetX;//获取点击时鼠标相对图片坐标
           var y=event.offsetY;
          $.ajax({
              url:"login.shtml", //ajax提交
              type:"post",
              data:{‘x‘:x,"y":y},
              success:function(data){
                 
                  alert(data)
                    obj.src=obj.src+"?date="+new Date();
              }
          })
    });
})


</script>
</head>
<body>
        <img id="image" src="${pageContext.request.contextPath}/captcha.svl" style="cursor: pointer;" >
</body>
</html>

 

服务端

package cn.gdin.captcha;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class Login
 */
@WebServlet("/Login")
public class Login extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
   
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.setContentType("text/html;charset=utf-8"); //设置编码
        //获取前端传来的坐标

        String xs=request.getParameter("x");   
        String ys=request.getParameter("y");
        HttpSession session = request.getSession();

        String str = (String) session.getAttribute("gap");//获取session中的gap
        if(str==null){ 
            response.getWriter().write("验证码超时");
            return;
        }
        String[] split2 = str.split(":"); 
        int x=    Integer.parseInt(xs);
        int y=Integer.parseInt(ys);
        int x1=    Integer.parseInt(split2[0]);
        int y1=Integer.parseInt(split2[1]);
        if(x1-2<x && x<x1+22 && y1-22<y && y<y1+2){  //若前端上传的坐标在session中记录的坐标的一定范围内则验证成功
            response.getWriter().write("验证成功");
        }else{
            response.getWriter().write("验证失败");
        }
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

 

 

----------------------------------------------以下是我自己改造的------------------------------

@Action("/test")
    public void test () throws IOException {
         Random random = new Random();
        
        int height = 220;  //图片高
        int width = 220;  //图片宽
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics2D g =  (Graphics2D) image.getGraphics();
        String picPath= "d:/a.png";  //读取本地图片,做背景图片
   
        
        g.drawImage(ImageIO.read(new File(picPath)), 0, 20, width, height, null); //将背景图片从高度20开始
        
   
        g.setColor(Color.white);  //设置颜色
        g.drawRect(0, 0, width-1, height-1); //画边框
    
        g.setFont(new Font("宋体",Font.BOLD,20)); //设置字体
        Integer x=null,y=null;  //用于记录坐标
        String target=null; // 用于记录文字
        for(int i=0;i<4;i++){  //随机产生4个文字,坐标,颜色都不同
            g.setColor(new Color(random.nextInt(50)+200, random.nextInt(150)+100, random.nextInt(50)+200));
            String str=getRandomChineseChar();
            int a=random.nextInt(width-100)+50;
            int b=random.nextInt(height-70)+55;
            if(x==null){
                x=a; //记录第一个x坐标
            }
            if(y==null){
                y=b;//记录第一个y坐标
            }
            if(target==null){
                target=str; //记录第一个文字
            }
            g.drawString(str, a, b);
        }
        g.setColor(Color.white);  
        g.drawString("点击"+target, 0,20);//写入验证码第一行文字  “点击..”
        request.getSession().setAttribute("gap",x+":"+y);//将坐标放入session
        System.out.println("gap:"+x+":"+y);
        ServletOutputStream out = response.getOutputStream();
        //5.释放资源
        g.dispose();
        //6.利用ImageIO进行输出
        ImageIO.write(image, "jpg", out); //将图片输出
        out.flush();
    }
    
    public  String getRandomChineseChar()
    {
              String str = null;
              int hs, ls; 
              Random random = new Random();
              hs = (176 + Math.abs(random.nextInt(39))); 
              ls = (161 + Math.abs(random.nextInt(93)));
              byte[] b = new byte[2];
              b[0] = (new Integer(hs).byteValue());
              b[1] = (new Integer(ls).byteValue());
              try
              {
                  str = new String(b, "GBk"); //转成中文
              }
              catch (UnsupportedEncodingException ex)
              {
                  ex.printStackTrace();
              }
              return str;
    }

 











































































































































































以上是关于java实现点击图片文字验证码的主要内容,如果未能解决你的问题,请参考以下文章

验证码的识别

(原创)牛逼!通过Python做文字识别到破解图片验证码

java 登陆时的验证码怎么做?

登录验证码

java实现一个验证码图片的功能

.net点选验证码实现思路分享