Java 验证码

 工具类

package net.yierde.web.param;


import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

/**
 * 赵朝阳
 */
public class CaptchaConfig {

    //对外提供的功能有三个,分别把他们定义成方法,并且是public;
//生成验证码;
//输出验证码;
//对外提供验证码的正确答案;
//生成验证码(BufferedImage)是一个带缓冲区的图像类
    private int width=300;
    private int height=150;

    private String codes="23456789qwertyuiopkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM";//验证码字符库;
    private String []ziti= {"宋体","华文楷体","黑体","微软雅黑","楷体_GB2312"};
    //生成验证文本;
    public String text;
    //定义一个随机数生成器;
    private Random s=new Random();

    //生产随机字符;
    char randomchar() {
        int index=s.nextInt(codes.length());
        return codes.charAt(index);

    }

//获取随机颜色;

    private Color randomColor() {
//RGB三个颜色组合在一起;
        int red=s.nextInt(150);
        int green=s.nextInt(150);
        int blue=s.nextInt(150);
        return new Color(red,green,blue);

    }
//获取随机背景颜色;

    private Color raColor() {
//RGB三个颜色组合在一起;
        int rs=s.nextInt(151)+90;
        int se=s.nextInt(151)+90;
        int po=s.nextInt(151)+90;
        return new Color(rs,se,po);

    }

    private Color bgColor = raColor();//设置随机背景颜色

    private Font randomFont() {//生成随机字体的方法;
        int indx=s.nextInt(ziti.length);//字体名称;
        String zit =ziti[indx];//字体名称;
        int style=s.nextInt(4);
        int size=s.nextInt(10)+100;
        return new Font(zit,style,size);


    }

    // 画干扰线
    private void drawLine(BufferedImage image) {
        int num=6;//干扰线数量;
        Graphics2D g2=(Graphics2D) image.getGraphics();//得到画笔;

        for (int i = 0; i < num; i++) {
            int x1 = s.nextInt(width/2); // 起点 x 坐标
            int y1 = s.nextInt(height/2); // 起点 y 坐标
            int x2 = s.nextInt(width); // 终点 x 坐标
            int y2 = s.nextInt(height); // 终点 y 坐标
            g2.setStroke(new BasicStroke(2F));//设置线条特征,1.5f为线的宽度;
            g2.setColor(randomColor());//干扰线颜色;
            g2.drawLine(x1, y1, x2, y2); //画线;
        }
    }


    // 画噪点
    private void zapdian(BufferedImage image) {
        int num=700;//干扰噪点数量;

        Graphics2D g2=(Graphics2D) image.getGraphics();//得到画笔;

        for (int i = 0; i < num; i++) {
            int x1 = s.nextInt(width); // 起点 x 坐标
            int y1 = s.nextInt(width); // 起点 y 坐标
            g2.setStroke(new BasicStroke(2F));//设置线条特征,1.5f为线的宽度;
            g2.setColor(randomColor());//干噪点颜色;
            g2.drawOval(x1, y1, 2, 2); //画线;


        }
    }



    public BufferedImage createImage() {//绘制验证码

        System.out.println("createImage");
        BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);//TYPE_INT_BGR(red);
//填充颜色;
        Graphics2D g2=(Graphics2D) image.getGraphics();//获取对应这个图片的一只画笔;
        g2.setColor(bgColor);//让画笔取色;
        g2.fillRect(0,0,width,height);//填充一个矩型;
        g2.setColor(new Color(250, 0, 0));//在构造一个颜色;
        g2.drawRect(0, 0, width-1, height-1);//画一个矩形框;
        StringBuilder stringBuilders = new StringBuilder();

        for(int i=0;i<4;i++) {//循环四此
            String s=randomchar()+"";
            stringBuilders.append(s);
            g2.setColor(randomColor());//让画笔在取一个颜色;
            g2.setFont(randomFont());//设置一个字体
            int x=width/4*i;
            int y=height/2+20;
            g2.drawString(s, x, y);//向图片上写字
        }
        text= stringBuilders.toString();
        drawLine(image); // 绘制干扰线
        zapdian(image);//绘制噪点
        return image;
    }

    //输出验证码
//第一个参数内存中的图片
//第二个参数,输出的目标可以是文件,也可以是网页 OutputStream
    public void output(BufferedImage image, OutputStream out) throws IOException {

        System.out.println("output");
        ImageIO.write(image,"JPEG",out);//输出矩形图片,这个方法可能会出现异常,所以我也要声明一下,我的output方法也可能会出现IOException异常;
    }

//对外提供验证码的正确答案

    public String getText() {
        return text;
    }
}

 页面的跳转,这里使用的response 直接放在请求体中去使用,不用下载到本地去使用

	@GetMapping("/yzm")
	public void yangzhengma(HttpServletResponse response){
		//                生成验证码
		CaptchaConfig r = new CaptchaConfig();
		//		r.createImage();
		System.out.println("Controller类r=====>"+r);
		BufferedImage img = r.createImage();
		System.out.println("Controller类img====>"+img);
		try {
			r.output(img,response.getOutputStream());
			System.out.println("验证码的答案是:"+r.getText());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

//工具类二
@RestController
@RequestMapping("/base")
public class CodeController {
    /**
     * 验证码
     * @param response 验证码图片的输出
     * @return 返回ajax
     */
    @GetMapping("/getCode")
    public AjaxResult getCode( HttpServletResponse response) {
        //                生成验证码
        CaptchaConfig r = new CaptchaConfig();
        BufferedImage img = r.createImage();
//		验证码答案
        String yzmContent = r.getText();
//        // 保存验证码信息 ,IdUtils为 id工具生成器,可以用UUId来生成
        String uuid = IdUtils.simpleUUID();
//        用一个常量加上uuid
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
//       RedisUtil类  放到redis中
        RedisUtil.set(verifyKey,yzmContent.toLowerCase());
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
            ImageIO.write(img, "jpg", os);
        }
        catch (IOException e)
        {
            return AjaxResult.error(e.getMessage());
        }
        Map<String ,String> result = new HashMap<String,String>();
        result.put("uuid",uuid);
        result.put("img", Base64.encode(os.toByteArray()));

        return AjaxResult.success(result);

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java验证码识别程序需要用到一些图像处理的,比如OpenCV或者JavaCV。以下是一个简单的验证码识别程序的示例: ```java import org.bytedeco.opencv.opencv_core.*; import org.bytedeco.opencv.global.opencv_imgcodecs; import org.bytedeco.opencv.global.opencv_imgproc; import java.util.ArrayList; import java.util.List; public class CaptchaRecognition { public static void main(String[] args) { String captchaPath = "captcha.png"; // 验证码图片路径 Mat captcha = opencv_imgcodecs.imread(captchaPath); Mat gray = new Mat(); opencv_imgproc.cvtColor(captcha, gray, opencv_imgproc.COLOR_BGR2GRAY); Mat thresh = new Mat(); opencv_imgproc.threshold(gray, thresh, 0, 255, opencv_imgproc.THRESH_BINARY_INV | opencv_imgproc.THRESH_OTSU); List<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); opencv_imgproc.findContours(thresh, contours, hierarchy, opencv_imgproc.RETR_EXTERNAL, opencv_imgproc.CHAIN_APPROX_SIMPLE); StringBuilder captchaCode = new StringBuilder(); for (MatOfPoint contour : contours) { Rect rect = opencv_imgproc.boundingRect(contour); if (rect.width() < 10 || rect.height() < 10) { continue; } Mat roi = new Mat(thresh, rect); String code = recognizeCharacter(roi); captchaCode.append(code); } System.out.println("验证码:" + captchaCode.toString()); } private static String recognizeCharacter(Mat roi) { // 这里可以使用机器学习算法或者模板匹配来实现字符识别 // 这里为了简单起见,直接将roi转换成字符串返回 return roi.toString(); } } ``` 以上代码中,我们首先读取验证码图片,并将其转换成灰度图像。然后使用二值化算法对图像进行处理,使得字符的轮廓更加明显。接着使用OpenCV提供的`findContours`函数找到图像中所有的轮廓。对于每一个轮廓,我们使用`boundingRect`函数得到该轮廓的矩形框,并判断其是否是一个字符(这里通过简单的宽度和高度判断)。最后,我们将每一个字符的矩形框提取出来,并传入`recognizeCharacter`函数中进行识别。在`recognizeCharacter`函数中,我们可以使用机器学习算法或者模板匹配算法来实现字符识别。在这个示例中,我们直接将字符的像素矩阵转换成字符串返回,仅供参考。 这个示例只是一个简单的验证码识别程序,实际上验证码的形式非常多样,有些验证码还会加入干扰线、干扰点等技巧来防止机器识别。因此,实际应用中还需要根据具体情况来选择合适的算法,并进行调试和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值