Java生成图形验证码

今天分享一下如何生成图形验证码,图形验证码可以由前端生成,也可以由后端生成,下面分别介绍这两种方法,首先是前端生成

<el-form-item>  
<div style="display: flex">    
<el-input size="mid" v-model="code" style="width: 200px"></el-input>    
<span @click="refreshCode" style="cursor: pointer; flex: 1;">      
<Identify :identifyCode="ideCode"></Identify>   
</span>  
</div>
</el-form-item>

code用来接收验证码输入框中输入的验证码,identifyCode存储生成的验证码的内容,ideCodes为生成的验证码的规则

code: '',
// 图片验证码
ideCode: '',
// 验证码规则
ideCodes: '3456789ABCDEFGHGKMNPQRSTUVWXY',

验证码生成和验证:请求登录接口之前先验证输入的验证码是否正确,验证通过请求登录接口

login() {   
    //验证二维码是否正确
	if (this.code !== 
	this.ideCode.toLowerCase()) {     
		this.$message({       
			type: "error",       
			message: "验证码错误"     
			})     
		return;   
		}
//请求登录接口
},
// 切换验证码
refreshCode() {  
	this.ideCode = ''  	
	this.makeCode(this.ideCodes, 4)
	},
// 生成随机验证码
makeCode(o, l) {  
	for (let i = 0; i < l; i++) {    
	this.ideCode += 
	this.ideCodes[Math.floor(Math.random() * (this.ideCodes.length))]  
	}
}

​

后端生成:后端生成在写法上要简单得多,但是,后端生成和验证时每次生成、刷新和验证都需要请求后端接口吗,效率比较低

private LineCaptcha lineCaptcha;//hutool的captcha包,包别导错

public void getCode(HttpServletResponse response) throws IOException {
	lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);    
	//图形验证码写出,可以写出到文件,也可写出到流    
	lineCaptcha.write(response.getOutputStream());    
	//输出code    
	Console.log(lineCaptcha.getCode());    
	response.getOutputStream().close();
}

验证时只需要lineCaptcha.verify()方法进行验证,输入的验证码作为lineCaptcha.verify()方法的入参,即可验证对错

前端代码:div包裹验证码输入框,用img标签显示验证码

<div style="float: left">  
	<el-form-item prop="gettext">    
	<el-input style="margin-bottom:3px;width: 150px" placeholder="请输入验证码" v-model="user.gettext"></el-input>  
	</el-form-item>
</div>
<img src="完整的url" style="margin-left:10px;width: 100px; height: 50px"     onclick="this.src=this.src+'?'">

第二种方法写起来简单,但是这种写法不论是生成、刷新还是检验验证码对错都需要发送请求,最后登录时还要发送请求,太过占用资源,前端生成验证码时,只需要在登陆时发送请求,验证码的生成、刷新和验证都在前端完成,不需要发送请求,因此这里推荐使用第一种,不推荐第二种。

---------------------------------------------------------------------------------------------------------------------------------

附:Identify.vue文件

<template>
  <div class="s-canvas">
    <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
  </div>
</template>
<script>
export default {
  name: 'Identify',
  props: {
    identifyCode: {
      type: String,
      default: '1234'
    },
    fontSizeMin: {
      type: Number,
      default: 28
    },
    fontSizeMax: {
      type: Number,
      default: 40
    },
    backgroundColorMin: {
      type: Number,
      default: 180
    },
    backgroundColorMax: {
      type: Number,
      default: 240
    },
    colorMin: {
      type: Number,
      default: 50
    },
    colorMax: {
      type: Number,
      default: 160
    },
    lineColorMin: {
      type: Number,
      default: 40
    },
    lineColorMax: {
      type: Number,
      default: 180
    },
    dotColorMin: {
      type: Number,
      default: 0
    },
    dotColorMax: {
      type: Number,
      default: 255
    },
    contentWidth: {
      type: Number,
      default: 112
    },
    contentHeight: {
      type: Number,
      default: 40
    }
  },
  methods: {
    // 生成一个随机数
    randomNum (min, max) {
      return Math.floor(Math.random() * (max - min) + min)
    },
    // 生成一个随机的颜色
    randomColor (min, max) {
      var r = this.randomNum(min, max)
      var g = this.randomNum(min, max)
      var b = this.randomNum(min, max)
      return 'rgb(' + r + ',' + g + ',' + b + ')'
    },
    drawPic () {
      var canvas = document.getElementById('s-canvas')
      var ctx = canvas.getContext('2d')
      ctx.textBaseline = 'bottom'
      // 绘制背景
      ctx.fillStyle = this.randomColor(
          this.backgroundColorMin,
          this.backgroundColorMax
      )
      ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
      // 绘制文字
      for (let i = 0; i < this.identifyCode.length; i++) {
        this.drawText(ctx, this.identifyCode[i], i)
      }
      this.drawLine(ctx)
      this.drawDot(ctx)
    },
    drawText (ctx, txt, i) {
      ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
      ctx.font =
          this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei'
      var x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))
      var y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
      var deg = this.randomNum(-30, 30)
      // 修改坐标原点和旋转角度
      ctx.translate(x, y)
      ctx.rotate(deg * Math.PI / 270)
      ctx.fillText(txt, 0, 0)
      // 恢复坐标原点和旋转角度
      ctx.rotate(-deg * Math.PI / 270)
      ctx.translate(-x, -y)
    },
    drawLine (ctx) {
      // 绘制干扰线
      for (let i = 0; i < 2; i++) {
        ctx.strokeStyle = this.randomColor(
            this.lineColorMin,
            this.lineColorMax
        )
        ctx.beginPath()
        ctx.moveTo(
            this.randomNum(0, this.contentWidth),
            this.randomNum(0, this.contentHeight)
        )
        ctx.lineTo(
            this.randomNum(0, this.contentWidth),
            this.randomNum(0, this.contentHeight)
        )
        ctx.stroke()
      }
    },
    drawDot (ctx) {
      // 绘制干扰点
      for (let i = 0; i < 20; i++) {
        ctx.fillStyle = this.randomColor(0, 255)
        ctx.beginPath()
        ctx.arc(
            this.randomNum(0, this.contentWidth),
            this.randomNum(0, this.contentHeight),
            1,
            0,
            2 * Math.PI
        )
        ctx.fill()
      }
    }
  },
  watch: {
    identifyCode () {
      this.drawPic()
    }
  },
  mounted () {
    this.drawPic()
  }
}
</script>
<style scoped>
.s-canvas {
  height: 38px;
}
.s-canvas canvas{
  margin-top: 1px;
  margin-left: 8px;
}
</style>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个简单的Java代码,用于生成验证码图片。 ```java import java.awt.*; import java.awt.image.BufferedImage; import java.util.Random; import javax.imageio.ImageIO; import java.io.*; public class CaptchaGenerator { private static final int WIDTH = 120; private static final int HEIGHT = 40; private static final int FONT_SIZE = 25; private static final int CODE_LENGTH = 4; private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; public static void main(String[] args) { BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) image.getGraphics(); Random random = new Random(); // 设置背景色 g.setColor(Color.WHITE); g.fillRect(0, 0, WIDTH, HEIGHT); // 生成随机验证码 StringBuilder code = new StringBuilder(); for (int i = 0; i < CODE_LENGTH; i++) { int index = random.nextInt(CHARACTERS.length()); char c = CHARACTERS.charAt(index); code.append(c); } // 绘制验证码 g.setFont(new Font("Arial", Font.BOLD, FONT_SIZE)); for (int i = 0; i < CODE_LENGTH; i++) { int x = i * WIDTH / CODE_LENGTH + 10; int y = HEIGHT / 2 + FONT_SIZE / 2 - 5; g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256))); g.drawString(String.valueOf(code.charAt(i)), x, y); } // 添加干扰线 for (int i = 0; i < 10; i++) { int x1 = random.nextInt(WIDTH); int y1 = random.nextInt(HEIGHT); int x2 = random.nextInt(WIDTH); int y2 = random.nextInt(HEIGHT); g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256))); g.drawLine(x1, y1, x2, y2); } // 输出验证码图片 try { ImageIO.write(image, "JPEG", new File("captcha.jpg")); } catch (IOException e) { e.printStackTrace(); } } } ``` 该代码生成一个120x40像素的验证码图片,包含4个字符,每个字符由字母和数字组成。字体大小为25,背景为白色,字符颜色随机。同时,还添加了10条干扰线。 输出的验证码图片保存在当前目录下的captcha.jpg文件中。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值