kaptcha插件图形验证码实践

 

1.pom.mxl配置文件加入kaptcha依赖:   

    <!--Google生成图片二维码jar-->
        <dependency>
            <groupId>com.google.code</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

2.实现com.google.code.kaptcha.GimpyEngine接口:

package com.txyzm.utils.kaptcha;

import com.google.code.kaptcha.GimpyEngine;
import com.google.code.kaptcha.util.Configurable;

import java.awt.*;
import java.awt.image.BufferedImage;

public class TxyzmGimpyEngine extends Configurable implements GimpyEngine{

    @Override
    public BufferedImage getDistortedImage(BufferedImage baseImage)
      {
        Graphics2D graph = (Graphics2D)baseImage.getGraphics();
        int imageHeight = baseImage.getHeight();
        int imageWidth = baseImage.getWidth();

//        int horizontalLines = imageHeight / 7;
//        int verticalLines = imageWidth / 7;

//        int horizontalGaps = imageHeight / (horizontalLines + 1);
//        int verticalGaps = imageWidth / (verticalLines + 1);

//        for (int i = horizontalGaps; i < imageHeight; i += horizontalGaps)
//        {
//          graph.setColor(Color.blue);
//          graph.drawLine(0, i, imageWidth, i);
//        }
//
//        for (int i = verticalGaps; i < imageWidth; i += verticalGaps)
//        {
//          graph.setColor(Color.red);
//          graph.drawLine(i, 0, i, imageHeight);
//        }

        
        graph.setColor(Color.red);
        graph.drawLine(0, 25, imageWidth, 25);
        
        /*graph.setColor(Color.red);
        graph.drawLine(5, 0, 5, imageHeight);*/
        
        int[] pix = new int[imageHeight * imageWidth];
        int j = 0;

        for (int j1 = 0; j1 < imageWidth; j1++)
        {
          for (int k1 = 0; k1 < imageHeight; k1++)
          {
            pix[j] = baseImage.getRGB(j1, k1);
            j++;
          }

        }

        double distance = ranInt(imageWidth / 4, imageWidth / 3);

        int widthMiddle = baseImage.getWidth() / 2;
        int heightMiddle = baseImage.getHeight() / 2;

        for (int x = 0; x < baseImage.getWidth(); x++)
        {
          for (int y = 0; y < baseImage.getHeight(); y++)
          {
            int relX = x - widthMiddle;
            int relY = y - heightMiddle;

            double d1 = Math.sqrt(relX * relX + relY * relY);
            if (d1 >= distance) {
              continue;
            }
            int j2 = widthMiddle + (int)(fishEyeFormula(d1 / distance) * distance / d1 * (x - widthMiddle));

            int k2 = heightMiddle + (int)(fishEyeFormula(d1 / distance) * distance / d1 * (y - heightMiddle));

            baseImage.setRGB(x, y, pix[(j2 * imageHeight + k2)]);
          }

        }

        return baseImage;
      }

      private int ranInt(int i, int j)
      {
        double d = Math.random();
        return (int)(i + (j - i + 1) * d);
      }

      private double fishEyeFormula(double s)
      {
        if (s < 0.0D)
          return 0.0D;
        if (s > 1.0D) {
          return s;
        }
        return -0.75D * s * s * s + 1.5D * s * s + 0.25D * s;
      }

}

 

3.实现com.google.code.kaptcha.text.WordRenderer接口:

package com.txyzm.utils.kaptcha;

import com.google.code.kaptcha.text.WordRenderer;
import com.google.code.kaptcha.util.Configurable;

import java.awt.*;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;
import java.util.Random;

public class TxyzmWordRenderer extends Configurable implements WordRenderer{

     @Override
     public BufferedImage renderWord(String word, int width, int height) {  
        int fontSize = getConfig().getTextProducerFontSize();  
        // 这个地方我们自定义了验证码文本字符样式,虽然是可以配置的,但是字体展示都粗体,我们希望不是粗体就只有自定义这个渲染类了  
        String paramName = "kaptcha.textproducer.font.names";  
        String paramValue = (String)getConfig().getProperties().get(paramName);  
        String fontNames[] = paramValue.split(",");  
        Font fonts[] = new Font[fontNames.length];  
        
        //Font.PLAIN 普通   Font.ITALIC 斜体  Font.BOLD 加粗 
        for(int i = 0; i < fontNames.length; i++){  
            fonts[i] = new Font(fontNames[i], Font.PLAIN, fontSize);  
        }  
        
        java.awt.Color color = getConfig().getTextProducerFontColor();  
        int charSpace = getConfig().getTextProducerCharSpace();  
        BufferedImage image = new BufferedImage(width, height, 2);  
        Graphics2D g2D = image.createGraphics();  
          
        g2D.setColor(color);  
        RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
        hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));  
          
        g2D.setRenderingHints(hints);  
        java.awt.font.FontRenderContext frc = g2D.getFontRenderContext();  
        Random random = new Random();  
        int startPosY = (height - fontSize) / 5 + fontSize;  
        char wordChars[] = word.toCharArray();  
        Font chosenFonts[] = new Font[wordChars.length];  
        int charWidths[] = new int[wordChars.length];  
        int widthNeeded = 0;  
        for(int i = 0; i < wordChars.length; i++)  
        {  
            chosenFonts[i] = fonts[random.nextInt(fonts.length)];  
            char charToDraw[] = {  
                wordChars[i]  
            };  
            GlyphVector gv = chosenFonts[i].createGlyphVector(frc, charToDraw);  
            charWidths[i] = (int)gv.getVisualBounds().getWidth();  
            if(i > 0)  
                widthNeeded += 2;  
            widthNeeded += charWidths[i];  
        }  
  
        int startPosX = (width - widthNeeded) / 2;  
        for(int i = 0; i < wordChars.length; i++)  
        {  
            g2D.setFont(chosenFonts[i]);  
            char charToDraw[] = {  
                wordChars[i]  
            };  
            g2D.drawChars(charToDraw, 0, charToDraw.length, startPosX, startPosY);  
            startPosX = startPosX + charWidths[i] + charSpace;  
        }  
  
        return image;  
    }  

}

4.spring配置文件,实例化com.google.code.kaptcha.impl.DefaultKaptcha类:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        ">

    
    <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
        <property name="config">
            <bean class="com.google.code.kaptcha.util.Config">
                <constructor-arg>
                    <props>
                        <prop key="kaptcha.border">no</prop><!--是否有边框 -->
                        <prop key="kaptcha.background.clear.from">240,240,240</prop>
                        <prop key="kaptcha.background.clear.to">240,240,240</prop>
                        <prop key="kaptcha.textproducer.font.color">204,128,255</prop>
                        <prop key="kaptcha.image.width">125</prop>
                        <prop key="kaptcha.image.height">45</prop>
                        <prop key="kaptcha.textproducer.font.size">35</prop>
                        <prop key="kaptcha.textproducer.char.length">4</prop>
                        <prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
                        <prop key="kaptcha.obscurificator.impl">com.txyzm.utils.kaptcha.TxyzmGimpyEngine</prop>
                        <prop key="kaptcha.background.impl">com.txyzm.utils.kaptcha.TxyzmBackgroundProducer</prop>
                        <prop key="kaptcha.word.impl">com.txyzm.utils.kaptcha.TxyzmWordRenderer</prop>
                    </props>
                </constructor-arg>
            </bean>
        </property>
    </bean>
</beans>

5.生成用图形码:

package com.txyzm.controller;


import com.google.code.kaptcha.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 图形验证码
 *
 */
@Controller
@RequestMapping("/txyzm/Txyzm")
public class TxyzmController {
    
    private static Logger logger = LoggerFactory.getLogger(TxyzmController.class);

    @Autowired
    private Producer captchaProducer;


    private static final String QCORE_PREFIX="imageQcore_";
    

    /**
     * 
     * 获取图片验证码
     * @return
     */
    @RequestMapping(value = "/createCaptchaImage", method = RequestMethod.GET)
    @ResponseBody
    public ModelAndView  createCaptchaImage(HttpServletRequest request, HttpServletResponse response) {
        
        response.setDateHeader("Expires", 0);  
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");  
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");  
        response.setHeader("Pragma", "no-cache");  
        response.setContentType("image/jpeg");  
        String capText = captchaProducer.createText();
        if(StringUtils.isNotBlank(capText)){
            BufferedImage bi = captchaProducer.createImage(capText);
            ServletOutputStream out = null;
            try{
                out = response.getOutputStream();
                ImageIO.write(bi, "jpg", out);
                out.flush();
            }catch(Exception ex){
                logger.error("生成图片验证码出错",ex);
            }finally{
                if(null != out){
                    try {
                        out.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
        return null;  
    }

}

6.图形码结果:

get访问:http://127.0.0.1:8080/txyzm/Txyzm/createCaptchaImage

响应结果:

 

7.相关参考:

https://blog.csdn.net/u010398838/article/details/79714403?utm_source=blogxgwz4

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cheneron

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值