kaptcha生成自定义图片验证码

因为项目需要,在发短信验证码 之前加上图片验证码。根据网上提供的资料很快的就实现了。因为kaptcha相当于是别人封装的,效果比较单一,所以在简单实现后自己试着改了改。虽然还是挺不好看的,还是想自己记录下来,下次就可以看自己的笔记而不用再在网上找了。

先写最简单的配置实现的吧,效果图:


1.maven项目首先配置pom文件导入jar包;

		<dependency>  <groupId>com.google.code.kaptcha</groupId>  <artifactId>kaptcha</artifactId>  <version>2.3</version>  </dependency>  

2..spring 配置文件配置

<!-- 配置kaptcha验证码 -->  <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">  <property name="config">  <bean class="com.google.code.kaptcha.util.Config">  <constructor-arg type="java.util.Properties">  <props>  
			<!-- 图片宽度 --><prop key="kaptcha.image.width">100</prop>  
			<!-- 图片高度 --><prop key="kaptcha.image.height">50</prop>  
			 <!-- 图片干扰线:放开注释不要干扰线 -->
	                   <!--  <prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.NoNoise</prop>   -->
			<!-- 验证码字符串 -->     <prop key="kaptcha.textproducer.char.string">0123456789</prop>  
			<!-- 验证码长度 --><prop key="kaptcha.textproducer.char.length">6</prop>  </props>  </constructor-arg>  </bean>  </property>  </bean> 


3.控制层:这段代码基本 上都大同小异。我是将验证码存入redis。

@RequestMapping("/kaptcha")  public SingtonResult<byte[]> handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{  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 token = (String) request.getAttribute("token");String capText = captchaProducer.createText();  //redis存值String  redisKey= "PC-kaptcha:"+token;rc.SetObjectByKey(redisKey, capText);BufferedImage bi = captchaProducer.createImage(capText);  ServletOutputStream out = response.getOutputStream();  ImageIO.write(bi, "jpg", out);  try {  out.flush();  } finally {  out.close();  }  return null;//SingtonResult.getSingtonSuccessInstance(b,"成功");} 

4.前端页面:

<img class="img-code" title="换一换" alt="加載中" src="/services/user/kaptcha.do" οnclick="this.src="/services/user/kaptcha.do?v="+Math.random()">

哦了,简单的很丑的图片验证码就好了。有没有发现在页面可能会格格不入,现在就需要自己去优化了。我没事的时候写了一下。

1.修改spring 配置如下:

<bean id="captchaProducer" class="com.qfy.common.utils.Kaptcha">  <property name="config">  <bean class="com.google.code.kaptcha.util.Config">  <constructor-arg type="java.util.Properties">  <props>  <!-- 图片宽度 --><prop key="kaptcha.image.width">117</prop>  <!-- 图片高度 --><prop key="kaptcha.image.height">40</prop>  <!-- 图片干扰线实现类 --><prop key="kaptcha.noise.impl">com.qfy.common.utils.Noise</prop>   <!-- 验证码字符串 --><prop key="kaptcha.textproducer.char.string">0123456789</prop>  <!-- 验证码长度 --><prop key="kaptcha.textproducer.char.length">6</prop>  <!-- 字体大小,默认40 --><prop key="kaptcha.textproducer.font.size">27</prop><!-- 字体样式 --><prop key="kaptcha.textproducer.font.names">微软雅黑</prop><prop key="kaptcha.background.clear.to">white</prop><!-- 是否需要边框:yes,no;默认yes --><prop key="kaptcha.border">no</prop><!-- 边框粗细:默认1 --><!--   <prop key="kaptcha.border.thickness">1</prop> --></props>  </constructor-arg>  </bean>  </property>  </bean>  
可以看到我自定义了干扰线类实现NoiseProducer
com.qfy.common.utils.Noise

package com.qfy.common.utils;import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.Random;import com.google.code.kaptcha.NoiseProducer;
import com.google.code.kaptcha.util.Configurable;/*** 图片验证码干扰线实现类* @author ptt**/
public class Noise extends Configurable implements NoiseProducer
{/*** Draws a noise on the image. The noise curve depends on the factor values.* Noise won't be visible if all factors have the value > 1.0f* * @param image*            the image to add the noise to* @param factorOne* @param factorTwo* @param factorThree* @param factorFour*/public void makeNoise(BufferedImage image, float factorOne,float factorTwo, float factorThree, float factorFour){// image sizeint width = image.getWidth();int height = image.getHeight();// the points where the line changes the stroke and directionPoint2D[] pts = null;Random rand = new Random();//   使用 float 坐标指定的三次参数曲线段。CubicCurve2D cc = new CubicCurve2D.Float(width * factorOne, height* rand.nextFloat(), width * factorTwo, height* rand.nextFloat(), width * factorThree, height* rand.nextFloat(), width * factorFour, height* rand.nextFloat());//  返回定义变平形状边界的迭代对象。PathIterator pi = cc.getPathIterator(null,2);Point2D tmp[] = new Point2D[200];int i = 0;// while pi is iterating the curve, adds points to tmp arraywhile (!pi.isDone()){float[] coords = new float[6];switch (pi.currentSegment(coords))//使用迭代返回当前路径段的坐标和类型,必须传入长度为 6 的 float 数组{case PathIterator.SEG_MOVETO: //SEG_MOVETO 和 SEG_LINETO 类型返回一个点case PathIterator.SEG_LINETO:case PathIterator.SEG_CUBICTO: //SEG_CUBICTO 返回 3 个点case PathIterator.SEG_QUADTO: //SEG_QUADTO 返回两个点tmp[i] = new Point2D.Float(coords[0], coords[1]);}i++;pi.next();}pts = new Point2D[i];System.arraycopy(tmp, 0, pts, 0, i);Graphics2D graph = (Graphics2D) image.getGraphics();graph.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON));// 设置干扰线10条;可以自行设置,每条干扰线的颜色位置都随机产生for (i = 0; i < 10; i++){int xs = rand.nextInt(width);  int ys = rand.nextInt(height);  int xe = xs+rand.nextInt(width/8);  int ye = ys+rand.nextInt(height/8);  graph.setColor(getColor());  graph.drawLine(xs, ys, xe, ye);  }graph.dispose();}/*** 干扰线 的颜色随机生成* @Title: getColor *@author :彭婷婷* @Description: TODO* @param @return   * @return Color    * @throws * @data  2017年3月31日下午1:32:32*/private Color getColor(){Random random = new Random();int red = random.nextInt(255);  int green = random.nextInt(255);  int blue = random.nextInt(255);  return new Color(red, green, blue);  }
}

试试现在的验证码就是这个样了。

还是有点 丑,将就吧,继续,干扰线五颜六色了,接下来就是字符串的色彩,字体改变了。当然,还是得在原有基础改写。

先修改spring配置文件

<bean id="captchaProducer" class="com.qfy.common.utils.Kaptcha">  

自己重写DefaultKaptcha类,实现Producer。贴代码

package com.qfy.common.utils;import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.Random;import com.google.code.kaptcha.BackgroundProducer;
import com.google.code.kaptcha.GimpyEngine;
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.text.TextProducer;
import com.google.code.kaptcha.text.WordRenderer;
import com.google.code.kaptcha.util.Configurable;/*** Default {@link Producer} implementation which draws a captcha image using* {@link WordRenderer}, {@link GimpyEngine}, {@link BackgroundProducer}.* Text creation uses {@link TextProducer}.*/
public class Kaptcha extends Configurable implements Producer
{private int width = 200;private int height = 50;/*** Create an image which will have written a distorted text.* * @param text*            the distorted characters* @return image with the text*/public BufferedImage createImage(String text){GimpyEngine gimpyEngine = getConfig().getObscurificatorImpl();BackgroundProducer backgroundProducer = getConfig().getBackgroundImpl();boolean isBorderDrawn = getConfig().isBorderDrawn();this.width = getConfig().getWidth();this.height = getConfig().getHeight();BufferedImage bi = renderWord(text, width, height);bi = gimpyEngine.getDistortedImage(bi);bi = backgroundProducer.addBackground(bi);Graphics2D graphics = bi.createGraphics();if (isBorderDrawn){drawBox(graphics);}return bi;}private void drawBox(Graphics2D graphics){Color borderColor = getConfig().getBorderColor();int borderThickness = getConfig().getBorderThickness();graphics.setColor(borderColor);if (borderThickness != 1){BasicStroke stroke = new BasicStroke((float) borderThickness);graphics.setStroke(stroke);}Line2D line1 = new Line2D.Double(0, 0, 0, width);graphics.draw(line1);Line2D line2 = new Line2D.Double(0, 0, width, 0);graphics.draw(line2);line2 = new Line2D.Double(0, height - 1, width, height - 1);graphics.draw(line2);line2 = new Line2D.Double(width - 1, height - 1, width - 1, 0);graphics.draw(line2);}/*** @return the text to be drawn*/public String createText(){return getConfig().getTextProducerImpl().getText();}public BufferedImage renderWord(String word, int width, int height){int fontSize = getConfig().getTextProducerFontSize();Font[] fonts = getConfig().getTextProducerFonts(fontSize);BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);Graphics2D g2D = image.createGraphics();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);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 = new char[]{wordChars[i]};GlyphVector gv = chosenFonts[i].createGlyphVector(frc, charToDraw);charWidths[i] = (int)gv.getVisualBounds().getWidth();if (i > 0){widthNeeded = widthNeeded + 2;}widthNeeded = widthNeeded + charWidths[i];}int startPosX = (width - widthNeeded) / 2;for (int i = 0; i < wordChars.length; i++){g2D.setColor(getColor());g2D.setFont(chosenFonts[i]);char[] charToDraw = new char[] {wordChars[i]};g2D.drawChars(charToDraw, 0, charToDraw.length, startPosX, startPosY);startPosX = startPosX + (int) charWidths[i] ;}return image;}private Color getColor(){Random random = new Random();int red = random.nextInt(255);  int green = random.nextInt(255);  int blue = random.nextInt(255);  return new Color(red, green, blue);  }
}


看看效果,贴图;


就这样就可以实现自己想要的效果了,不再是默认的黑白色了。效果就自己调节到满意为止就行了。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/61952.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Easy-Captcha验证码 生成以及校验(简单易懂)

目录 说明pom引入详解参数类使用easy-captcha 中提供了下面几种类源码说明 Captcha使用验证图解源码测试GitHub 说明 Java图形验证码&#xff0c;支持gif、中文、算术等类型&#xff0c;可用于Java Web、JavaSE等项目 pom引入 <dependency><groupId>com.github.w…

验证码生成原理即Python代码实现

验证码的生成步骤&#xff1a; 方法一&#xff1a;1.关键在于random能随机获取 2.首先建立一个字符串包含0-9&#xff0c;A-z&#xff08;可根据实际要求添加字符&#xff09;&#xff0c;命名为Number 3.一般验证码是既定长度&#xff0c;我们这里使用4-6位随机长度验证码&…

关于 小红书 x-sign 的数据的破解

该文章主要提供交流学习使用&#xff0c;请勿利用其进行不当行为&#xff01; 如本篇文章侵犯了贵公司的隐私&#xff0c;请联系我立刻删除&#xff01; 由于最近比较忙&#xff0c;暂时没有更新&#xff0c;这段时间会及时更新的 在获取 小红书 x-sign 时候发现数据为必须添…

邮箱发送验证码和短信发送验证码的学习笔记

邮箱发送验证码 //邮箱验证码public static boolean sendEmail(String emailaddress,String code) {try {HtmlEmail email new HtmlEmail();//不用更改email.setHostName("smtp.qq.com");// 发件者的邮箱 需要修改&#xff0c;126邮箱为smtp.126.com,163邮箱为smtp…

Kaptcha生成图片验证码

Kaptcha简介 kaptcha 是一个很有用的验证码生成工具。由于它是可配置的&#xff0c;有了它&#xff0c;你能够生成各种样式的验证码。 Kaptcha 是一个可高度配置的实用验证码生成工具&#xff0c;可自由配置的选项如&#xff1a; 验证码的字体验证码字体的大小验证码字体的字…

前后端分离java开发图形验证码+谷歌开源Kaptcha使用(Springboot+redis实现图形验证码校验)

文章目录 1.背景1.1 什么是短信-邮箱轰炸机1.2 公司带来的损失 2.如何避免自己的网站成为"肉鸡“或者被刷呢3.表单重复提交问题4.Kaptcha框架介绍5.前后端分离验证码实战开发-思路分析6.前后端分离验证码实战开发-后端代码5.1 pom.xml核心依赖5.2 KaptchaConfig配置类5.3 …

Qt音乐播放器实现(带歌词功能)

最近期末项目要写一个音乐播放器&#xff0c;作为新人头疼了好久&#xff0c;参考了各方文档&#xff0c;总算憋出来了一个&#xff0c;歌词功能用的是一个大佬实现的&#xff0c;然后我就调用了&#xff0c;就是我那个lyricwidget.cpp和头文件就是直接弄过来的&#xff0c;但是…

JavaWeb音乐网站开发:Ajax异步获取歌词文件并显示,以及实现音频与歌词对应同步的方法

在开发音乐网站或APP的时候&#xff0c;都必须要面对这一个问题&#xff1a;如何让正在播放的歌曲的歌词与音频对应&#xff1f;也就是歌曲正在唱哪一句对应显示这一句的歌词&#xff1f;这便是今天这篇博客主要谈论的主题&#xff0c;先抛开爬虫爬取这一说&#xff0c;今天讲的…

Android解析lrc里的歌词

解析记歌词的类。这是解析.lrc文件里的歌词。 解析歌词使用的是输入流&#xff0c;然后吧歌词和歌词时间放在JavaBean的列表里。具体代码如下&#xff1a; package com.zzm.android.Handler;import java.io.BufferedReader; import java.io.File; import java.io.FileInputStr…

iPhone上的lrc播放器可以在播放mp3文件时显示歌词

https://apps.apple.com/cn/app/%E6%96%B0lrc%E6%92%AD%E6%94%BE%E5%99%A82/id1535214306 长久以来&#xff0c;在iPhone上播放lrc字幕一直是一个大的问题。因为苹果自带的音乐播放器不支持lrc歌词字幕&#xff0c;而市面上也少有支持lrc歌词字幕的音乐播放器App。 现在&…

音乐歌词同步实现指南

有道友问了我这个问题&#xff0c;所以在这写了下思路首先&#xff0c;我默认你至少已经了解了h5的audio标签的相关属性&#xff0c;直入正题audio使用指南audio标签audio之HTML 事件属性 old歌词 一般的说&#xff0c;lyric文件由时间的tag标签组成&#xff0c;如截图所示 现在…

把乐谱换成c语言程序的软件,有没有什么软件可以把音乐换成简谱?

一、下载&#xff1a; 1。先把WAV或MP3转换成MIDI 下载地址&#xff1a; http://www.skycn.com/soft/10460.html 2。再把MIDI转成五线谱 下载地址&#xff1a; http://soft.pcnow.com.cn/soft/17237.shtml 二、安装&#xff1a; 1。安装MP3转MIDI工具&#xff0c;一直点下一步即…

安卓文字绘制和歌词器的简单实现

文章目录 安卓绘制文本的细节和歌词动画实战绘制简单文本绘制API绘制线设计多条线的原因 中心绘制x轴居中align居中宽度居中 正中心绘制 动画绘制原理过度绘制解决过度绘制 Demo点赞评论找我要哦 安卓绘制文本的细节和歌词动画实战 绘制文本有许多细节&#xff0c;这篇文章从绘…

歌词同步

歌词同步 前面的话歌词同步的需求歌词加载歌词显示歌曲播放时歌词的滚动计算歌词滚动范围如何同步歌词的滚动细节计算 鼠标拖拽时歌词的滚动自由滚动歌词 源码 前面的话 最近发现我们班同学做了一个很酷的Demo&#xff0c;这个Demo实现了一个很不错的歌词同步&#xff0c;着实…

终于等到你!Guitar Pro 8.1版本简谱功能首发

Guitar Pro是一款非常流行的音乐制谱软件它不仅适用于吉他谱还可以用于其他乐器的制谱。历经5年多时间研发Guitar Pro 在2022年正式发布了全新的8系列版本时隔不到1年Guitar Pro又给广大中国用户带来期盼已久的简谱功能下面让我带领大家一起体验吧 软件souurl.cn/BPln7d 图1 G…

人工智能火爆 国内这几家计算机视觉公司值得关注

&#xfeff;&#xfeff; 人工智能自降生以来就仿佛自带光环、备受瞩目。尤其是今年&#xff0c;国务院印发的《新一代人工智能发展规划》中提出&#xff0c;到2030年使中国人工智能理论、技术与应用总体达到世界领先水平&#xff0c;成为世界主要人工智能创新中心&#xff0c…

国内最值得关注的10家人工智能语音识别公司

在谈人工智能的时候&#xff0c;一定不能不谈语音识别&#xff0c;语音识别是人机交互的入口&#xff0c;是指机器/程序接收、解释声音&#xff0c;或理解和执行口头命令的能力。目前国内外都有公司在语音领域有所投入&#xff0c;其中包括才成立几年的初创企业&#xff0c;也包…

运气好到了一品

今天运气好&#xff0c;连续几把都赢了&#xff0c;一口气从布衣五品冲上了智贤一品&#xff0c;纪念一下。

到了智贤一品

朋友今天运气不错&#xff0c;今天连续打几把&#xff0c;都赢了&#xff0c;所以品级从智贤五品一路升级到了智贤一品&#xff0c;他很开心&#x1f601;。

之伏一品纪念

昨天运气不错&#xff0c;玩了几把&#xff0c;结果巴巴赢&#xff0c;从智贤一品升级到了之伏五品&#xff0c;之伏往升级的需要赢的次数就更多了&#xff0c;我感觉自己没啥希望了&#xff0c;有一个已经非常满足了。因为再过两个月会重新排名&#xff0c;重新从零开始升级。…