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