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();
            }

        }
}
相关推荐
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck2 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei2 小时前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml44 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~4 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616884 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端