Springboot整合百度OCR实现身份证识别

核心代码如下

java 复制代码
package cn.vastall.hrhs.core.controller.tyocr;

import com.alibaba.druid.util.Base64;
import com.alibaba.fastjson.JSONObject;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/ocr")
public class TigaController {
    private static final String ACCESS_TOKEN_HOST = "https://aip.baidubce.com/oauth/2.0/token?";
    private static final String OCR_HOST = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?";
    private static final String API_KEY = "vWdqmGdE4xEmYM6zfGnvTUrb";
    private static final String SECRET_KEY = "ajMSQLGWjzfSCY6IUHOv0YMybF95Anzq";


    // 获取百度云OCR的授权access_token
    public static String getAccessToken() {
        return getAccessToken(API_KEY, SECRET_KEY);
    }

    /**
     * 获取百度云OCR的授权access_token
     *
     * @param apiKey
     * @param secretKey
     * @return
     */
    public static String getAccessToken(String apiKey, String secretKey) {
        String accessTokenURL = ACCESS_TOKEN_HOST
                // 1. grant_type为固定参数
                + "grant_type=client_credentials"
                // 2. 官网获取的 API Key
                + "&client_id=" + apiKey
                // 3. 官网获取的 Secret Key
                + "&client_secret=" + secretKey;

        try {
            URL url = new URL(accessTokenURL);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            // 获取响应头
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "---->" + map.get(key));
            }

            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder result = new StringBuilder();
            String inputLine;
            while ((inputLine = bufferedReader.readLine()) != null) {
                result.append(inputLine);
            }
            JSONObject jsonObject = JSONObject.parseObject(result.toString());
            return jsonObject.getString("access_token");

        } catch (Exception e) {
            e.printStackTrace();
            System.err.print("获取access_token失败");
        }
        return null;
    }

    /**
     * 获取身份证识别后的数据
     *
     * @param imageUrl
     * @return
     */
    public static String getStringIdentityCard(File imageUrl) {
        // 身份证OCR的http URL+鉴权token
        String OCRUrl = OCR_HOST + "access_token=" + getAccessToken();
        // 对图片进行base64处理
        String image = encodeImageToBase64(imageUrl);
        // 请求参数
        String requestParam = "detect_direction=true&id_card_side=front&image=" + image;

        try {
            // 请求OCR地址
            URL url = new URL(OCRUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 设置请求方法为POST
            connection.setRequestMethod("POST");

            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("apiKey", API_KEY);
            connection.setDoOutput(true);
            connection.getOutputStream().write(requestParam.getBytes(StandardCharsets.UTF_8));
            connection.connect();

            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
            StringBuilder result = new StringBuilder();
            String inputLine;
            while ((inputLine = bufferedReader.readLine()) != null) {
                result.append(inputLine);
            }
            bufferedReader.close();
            return result.toString();
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("身份证OCR识别异常");
            return null;
        }
    }

    /**
     * 对图片url进行Base64编码处理
     *
     * @param imageUrl
     * @return
     */
    public static String encodeImageToBase64(File imageUrl) {
        // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        byte[] data = null;
        try {
            InputStream inputStream = new FileInputStream(imageUrl);
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();

            // 对字节数组Base64编码
            return URLEncoder.encode(Base64.byteArrayToBase64(data), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }


    /**
     * 提取OCR识别身份证有效信息
     *
     * @param
     * @return
     */
    @PostMapping("/uploadIdentity")
    public static Map<String, String> getIdCardInfo(MultipartFile image) throws Exception {
        File fileToFilemg = multipartFileToFile(image);
        String value = getStringIdentityCard(fileToFilemg);
        String side;

        Map<String, String> map = new HashMap<>();
        JSONObject jsonObject = JSONObject.parseObject(value);
        JSONObject words_result = jsonObject.getJSONObject("words_result");
        if (words_result == null || words_result.isEmpty()) {
            throw new SecurityException("请提供身份证图片");
        }
        for (String key : words_result.keySet()) {
            JSONObject result = words_result.getJSONObject(key);
            String info = result.getString("words");
            switch (key) {
                case "姓名":
                    map.put("name", info);
                    break;
                case "性别":
                    map.put("sex", info);
                    break;
                case "民族":
                    map.put("nation", info);
                    break;
                case "出生":
                    map.put("birthday", info);
                    break;
                case "住址":
                    map.put("address", info);
                    break;
                case "公民身份号码":
                    map.put("idNumber", info);
                    break;
                case "签发机关":
                    map.put("issuedOrganization", info);
                    break;
                case "签发日期":
                    map.put("issuedAt", info);
                    break;
                case "失效日期":
                    map.put("expiredAt", info);
                    break;
            }
        }
        return map;

    }


    
}

MultipartFile转File工具

java 复制代码
        /**
         * MultipartFile 转 File
         *
         * @throws Exception
         */
        public static File multipartFileToFile(MultipartFile file) throws Exception {
            File toFile = null;
            if (file.equals("") || file.getSize() <= 0) {
                file = null;
            } else {
                InputStream ins = null;
                ins = file.getInputStream();
                toFile = new File(file.getOriginalFilename());
                inputStreamToFile(ins, toFile);
                ins.close();
            }
            return toFile;
        }

        //获取流文件
        private static void inputStreamToFile(InputStream ins, File file) {
            try {
                OutputStream os = new FileOutputStream(file);
                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                os.close();
                ins.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 删除本地临时文件
         *
         * @param file
         */
        public static void delteTempFile(File file) {
            if (file != null) {
                File del = new File(file.toURI());
                del.delete();
            }

        }
}
相关推荐
考虑考虑17 小时前
Jpa使用union all
java·spring boot·后端
用户37215742613518 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊19 小时前
Java学习第22天 - 云原生与容器化
java
渣哥21 小时前
原来 Java 里线程安全集合有这么多种
java
间彧21 小时前
Spring Boot集成Spring Security完整指南
java
间彧21 小时前
Spring Secutiy基本原理及工作流程
java
Java水解1 天前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆1 天前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学1 天前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole1 天前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端