登录接口中图片验证码Tesseract-OCR识别Java脚本

发布于:2025-05-16 ⋅ 阅读:(61) ⋅ 点赞:(0)

项目上移植了研发部的产品,文档不全,项目上验证码功能无法关闭,又要做接口/性能测试,开发不配合(作为测试多么无奈),此方法识别命中率不高,仅作借鉴。
版本JDK11

import io.restassured.response.Response;
import net.sourceforge.tess4j.Tesseract;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import static io.restassured.RestAssured.given;

public class ImageCodeTess {
    /**
     * urlInfo基本信息
     * */
    public static String getUrl(String prototype,String host,String port,String uri){
        UrlInfo urlInfo = new UrlInfo();
        urlInfo.setPrototype(prototype);
        urlInfo.setHost(host);
        urlInfo.setPost(port);
        urlInfo.setUri(uri);
        return urlInfo.toString();
    }
    /**
     * 获取验证码的响应map
     * */
    public static Map<String,String> getImageBase64Map(String url){
        Map<String,String> map = new HashMap<>();
        Response response = given().when().get(url).then().extract().response();
        map.put("imageContent",response.jsonPath().get("imageContent"));
        # 登录接口要用到deviceId,和imageContent是绑定的
        map.put("deviceId",response.jsonPath().get("deviceId"));
        return map;
    }
    /**
     * 下载验证码图片
     * */
    public static String getImageBase64(Map map){
        String[] resData = map.get("imageContent").toString().split(";");
        String base64Image = resData[2];
        String imageStr = base64Image.substring(base64Image.lastIndexOf(",")+1);
        return imageStr;
    }

    /**
     * @Method downloadImageCode() 下载base64字符串转码的图片
     * @param ImageStr base64字符串
     * @param ImagePath 下载地址前缀
     * */
    public static String downloadImageCode(String ImageStr,String ImagePath) {
        /*
         * JDK11版本中针对sun.misc.BASE64Encoder 使用方法进行了修改升级.
         * jdk8中:
         *   BASE64Decoder decoder = new BASE64Decoder();
         *   byte[] bytes = decoder.decodeBuffer(str);
         * JDK11中变更为:java.util.Base64
         *   Base64.Decoder decoder = Base64.getMimeDecoder();
         *   byte[] bytes = decoder.decode(str);
         * */
        Base64.Decoder decoder = Base64.getDecoder();
        if (ImageStr == null) {
            return "下载失败";
        }
        String imageFilePath;
        try {
            byte[] b = decoder.decode(ImageStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }

            int rdm = (int) Math.random()*100;

            imageFilePath = ImagePath + System.currentTimeMillis() + rdm + ".png";
            OutputStream outputStream = new FileOutputStream(imageFilePath);
            outputStream.write(b);
            outputStream.flush();
            outputStream.close();

        } catch (Exception e) {
            return "下载失败";
        }
        return imageFilePath;
    }

    /**
     * 图片降噪处理,借鉴了某大佬的代码
     * */
    public static String removeBackground(String imagePath) {
        // RGB阈值
        int threshold = 500;
        String resultPath = null;
        try {
            BufferedImage bufferedImage = ImageIO.read(new File(imagePath));
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    Color color = new Color(bufferedImage.getRGB(x, y));
                    /*System.out.println("red:" + color.getRed() + ";green:" + color.getGreen() + ";blue:" + color.getBlue());*/
                    int num = color.getRed() + color.getGreen() + color.getBlue();
                    if (num >= threshold) {
                        bufferedImage.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
            for (int i = 0; i < width; i++) {
                Color color1 = new Color(bufferedImage.getRGB(i, 1));
                int num1 = color1.getRed() + color1.getGreen() + color1.getBlue();
                for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                        Color color = new Color(bufferedImage.getRGB(x, y));
                        int num = color.getRed() + color.getGreen() + color.getBlue();
                        if (num == num1) {
                            bufferedImage.setRGB(x, y, Color.WHITE.getRGB());
                        } else {
                            bufferedImage.setRGB(x, y, Color.BLACK.getRGB());
                        }
                    }
                }
            }

            resultPath = imagePath.substring(0, imagePath.lastIndexOf(".")) + "_1.png";
            File file = new File(resultPath);
            ImageIO.write(bufferedImage, "png", file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultPath.toString();
    }

    /**
     * 识别处理后的验证码图片
     * */
    public static String getImageCode(String ImageFilePath) {
        String result = null;
        try {
            Tesseract tesseract = new Tesseract();
            tesseract.setDatapath("C:/Program Files/Tesseract-OCR/tessdata");
            tesseract.setLanguage("eng");
            result = tesseract.doOCR(new File(ImageFilePath));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到