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

        }
}
相关推荐
《源码好优多》18 分钟前
基于Java Springboot出租车管理网站
java·开发语言·spring boot
余辉zmh1 小时前
【c++篇】:深入c++的set和map容器--掌握提升编程效率的利器
开发语言·c++
·云扬·4 小时前
Java IO 与 BIO、NIO、AIO 详解
java·开发语言·笔记·学习·nio·1024程序员节
求积分不加C4 小时前
Spring Boot中使用AOP和反射机制设计一个的幂等注解(两种持久化模式),简单易懂教程
java·spring boot·后端
枫叶_v5 小时前
【SpringBoot】26 实体映射工具(MapStruct)
java·spring boot·后端
东方巴黎~Sunsiny5 小时前
java-图算法
java·开发语言·算法
2401_857617626 小时前
汽车资讯新趋势:Spring Boot技术解读
java·spring boot·后端
小林学习编程7 小时前
从零开始理解Spring Security的认证与授权
java·后端·spring
写bug的羊羊7 小时前
Spring Boot整合Nacos启动时 Failed to rename context [nacos] as [xxx]
java·spring boot·后端
ad禥思妙想7 小时前
如何运行python脚本
开发语言·python