栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Java百度云身份证识别

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java百度云身份证识别

Java百度云身份证识别
  • 一、身份证识别工具类
  • 二、获取Token工具类
  • 三、java原生HTTP请求工具类
  • 四、使用

一、身份证识别工具类
package com.cndatacom.cloud1.cdchr.modules.hireinfo.common;


import com.alibaba.fastjson.JSONObject;
import com.cndatacom.cloud1.cdchr.common.exception.SFException;
import com.cndatacom.cloud1.cdchr.modules.hireinfo.dictdatautil.filter.DictDataListFilter;
import com.cndatacom.cloud1.cdchr.modules.hireinfo.entity.CdcHirebaseEntity;
import org.apache.commons.codec.binary.base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Component
public class IdCard {
    private static final Logger LOG = LoggerFactory.getLogger(IdCard.class);
    @Autowired
    private AuthService authService;
    private static final Map MSG = new HashMap() {{
//        put("normal","识别正常");
        put("reversed_side", "身份证正反面颠倒");
        put("non_idcard", "上传的图片中不包含身份证");
        put("blurred", "身份证模糊");
        put("other_type_card", "其他类型证照");
        put("over_exposure", "身份证关键字段反光或过曝");
        put("over_dark", "身份证欠曝(亮度过低)");
        put("unknown", "未知状态");
    }};

    public String getIdCard(String filePath, String frontAndBack) {
        LOG.info("进入百度云API身份证识别接口中[filePath=" + filePath + "][frontAndBack=" + frontAndBack + "]");

        // 请求url
        String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";

        LOG.info("正在读取文件[" + filePath + "]");
        byte[] imgData = new byte[0];
        try {
            imgData = FileUtil.readFileByBytes(filePath);
        } catch (IOException e) {
            LOG.error("FileUtil读取[" + filePath + "]异常,信息为:" + e.getMessage());
            throw new SFException("无法加载身份证照片");
        }
        String param = null;
        String accessToken = null;
        try {
            LOG.info("正在base64加密字节集");
            String imgStr = base64Util.encode(imgData);
            LOG.info("正在UTF-8编码");
            String imgParam = URLEncoder.encode(imgStr, "UTF-8");
            param = "id_card_side=" + frontAndBack + "&image=" + imgParam + "&detect_photo=true";
            // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
            LOG.info("正在获取调用百度云API接口的令牌");
            accessToken = authService.getAuth();//获取token
            LOG.info("令牌获取完成,准备调用接口");
        } catch (UnsupportedEncodingException e) {
            LOG.error("base64加密字节集 and UTF-8编码 异常,信息为:" + e.getMessage());
        }
        String result = null;
        try {
            result = HttpUtil.post(url, accessToken, param);
        } catch (Exception e) {
            LOG.error("调用百度云API身份证识别接口异常,信息为:" + e.getMessage());
            throw new SFException("身份证图片识别异常");
        }
        LOG.info("调用百度云API身份证识别接口返回结果为:" + result);
        Object image_status = JSONObject.parseObject(result).get("image_status");
        if (image_status != null && MSG.containsKey(image_status))
            throw new SFException(MSG.get(image_status));

        return result;

    }


    
    public static final Info getUserInfo(String idCard) {
        return new Info(idCard);
    }

    public static class Info {
        private String userName;
        private String nationId;
        private String nation;
        private String address;
        private String cardIdNo;
        private Date birthday;
        private String sex;
        private String photo;

        public Info(String idCard) {
            try {
                JSONObject json = JSONObject.parseObject(idCard);
                JSONObject words_result = json.getJSONObject("words_result");
                this.userName = words_result.getJSONObject("姓名").getString("words");
                LOG.info("识别身份证JSON结果[姓名]=[" + this.userName + "]");
                this.nation = words_result.getJSONObject("民族").getString("words");
                LOG.info("识别身份证JSON结果[民族]=[" + this.nation + "]");
                if (this.nation != null && this.nation.length() > 0) {
                    LOG.info("正在查找民族对应的code码");
                    List nation = DictDataListFilter.getDictDataBybaseType("nation");
                    List collect = nation.stream().filter(e -> {
                        String baseName = e.getbaseName();
                        baseName = baseName.substring(0, baseName.length() - 1);
                        if (baseName.equals(this.nation)) {
                            this.nation += "族";
                            return true;
                        }
                        return false;
                    }).collect(Collectors.toList());
                    this.nationId = collect.get(0).getbaseCode();
                }
                LOG.info("查找结果为["+this.nationId+"]");
                this.address = words_result.getJSONObject("住址").getString("words");
                LOG.info("识别身份证JSON结果[住址]=[" + this.address + "]");
                this.cardIdNo = words_result.getJSONObject("公民身份号码").getString("words");
                LOG.info("识别身份证JSON结果[公民身份号码]=[" + this.cardIdNo + "]");
                this.birthday = new SimpleDateFormat("yyyyMMdd").parse(words_result.getJSONObject("出生").getString("words"));
                LOG.info("识别身份证JSON结果[出生]=[" + this.birthday + "]");
                this.sex = words_result.getJSONObject("性别").getString("words").equals("男") ? "1" : "2";
                LOG.info("识别身份证JSON结果[性别]=[" + this.sex + "][1=男,2=女]");
                byte[] bytes = base64.decodebase64(json.getString("photo"));//获取结果中头像图片字节
                String headFilePath = IOUtil.outHeader(bytes);//输出到本地
                this.photo = headFilePath;
            } catch (Exception e) {
                LOG.error("IdCard Info 内部构造器在构造身份证基本信息时异常,信息为:" + e.getMessage());
            }
        }

        public String getUserName() {
            return userName;
        }

        public String getNation() {
            return nation;
        }

        public String getAddress() {
            return address;
        }

        public String getCardIdNo() {
            return cardIdNo;
        }

        public Date getBirthday() {
            return birthday;
        }

        public String getSex() {
            return sex;
        }

        public String getPhoto() {
            return photo;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public void setNation(String nation) {
            this.nation = nation;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public void setCardIdNo(String cardIdNo) {
            this.cardIdNo = cardIdNo;
        }

        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }

        public void setSex(String sex) {
            this.sex = sex;
        }

        public void setPhoto(String photo) {
            this.photo = photo;
        }

        public String getNationId() {
            return nationId;
        }

        public void setNationId(String nationId) {
            this.nationId = nationId;
        }
    }
}

二、获取Token工具类
package com.cndatacom.cloud1.cdchr.modules.hireinfo.common;

import com.cndatacom.cloud1.cdchr.common.utils.AesUtils;
import com.cndatacom.cloud1.cdchr.modules.sys.service.SysConfigService;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;


@Component
public class AuthService {
    @Autowired
    private SysConfigService sysConfigService;
//    @Value("${baidu.Id_card.app_key}")
//    public String appKey;
//    @Value("${baidu.Id_card.app_secret}")
//    public String appSecret;
//    @Value("${baidu.Id_card.access_token_valid_time}")
    public Long accessTokenValidTime = 2505600L; //有效时间  2505600L = 29天  2592000 = 30天
    public static Long accessTokenExpirationTime = null; //生成token的时候  时间==过期时间
    public static String token = null;
    
    public String getAuth() {

        if (token == null || ((System.currentTimeMillis() - accessTokenExpirationTime) / 60) > accessTokenValidTime) {
//            如果token是空  或者 系统的秒值-之前生成token时的秒值 > 有效时间29天  重新生成
            String baidu_appKey = sysConfigService.getValue("baidu_appKey");
            String baidu_appSecret = sysConfigService.getValue("baidu_appSecret");
            getAuth(AesUtils.decrypt(baidu_appKey), AesUtils.decrypt(baidu_appSecret));
        }
        return token;
    }

    
    public void getAuth(String ak, String sk) {
        // 获取token地址
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
                // 1. grant_type为固定参数
                + "grant_type=client_credentials"
                // 2. 官网获取的 API Key
                + "&client_id=" + ak
                // 3. 官网获取的 Secret Key
                + "&client_secret=" + sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String result = "";
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            
            System.err.println("result:" + result);
            JSONObject jsonObject = new JSONObject(result);
            String access_token = jsonObject.getString("access_token");
            accessTokenExpirationTime = System.currentTimeMillis();
            token = access_token;
        } catch (Exception e) {
            System.err.printf("获取token失败!");
            e.printStackTrace(System.err);
        }
    }

    public static final AuthService ok(){
        return new AuthService();
    }

}

三、java原生HTTP请求工具类
用于上传文件
package com.cndatacom.cloud1.cdchr.modules.hireinfo.common;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;


public class HttpUtil {

    public static String post(String requestUrl, String accessToken, String params)
            throws Exception {
        String contentType = "application/x-www-form-urlencoded";
        return HttpUtil.post(requestUrl, accessToken, contentType, params);
    }

    public static String post(String requestUrl, String accessToken, String contentType, String params)
            throws Exception {
        String encoding = "UTF-8";
        if (requestUrl.contains("nlp")) {
            encoding = "GBK";
        }
        return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
    }

    public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
            throws Exception {
        String url = requestUrl + "?access_token=" + accessToken;
        return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
    }

    public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
            throws Exception {
        URL url = new URL(generalUrl);
        // 打开和URL之间的连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        // 设置通用的请求属性
        connection.setRequestProperty("Content-Type", contentType);
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setUseCaches(false);
        connection.setDoOutput(true);
        connection.setDoInput(true);

        // 得到请求的输出流对象
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.write(params.getBytes(encoding));
        out.flush();
        out.close();

        // 建立实际的连接
        connection.connect();
        // 获取所有响应头字段
        Map> headers = connection.getHeaderFields();
        // 遍历所有的响应头字段
        for (String key : headers.keySet()) {
            System.err.println(key + "--->" + headers.get(key));
        }
        // 定义 BufferedReader输入流来读取URL的响应
        BufferedReader in = null;
        in = new BufferedReader(
                new InputStreamReader(connection.getInputStream(), encoding));
        String result = "";
        String getLine;
        while ((getLine = in.readLine()) != null) {
            result += getLine;
        }
        in.close();
        System.err.println("result:" + result);
        return result;
    }
}

四、使用
String idCard = this.idCard.getIdCard(filePath, "front");//前面
String idCard = this.idCard.getIdCard(filePath, "back");//背面

IdCard.Info = IdCard.getUserInfo(idCard);//当正面时可以调这个方法来获取信息
IdCard.Info内部类如下图

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/286068.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号