解析身份证照片信息

项目开发中,我们往往会遇到一些特殊的需求,下面我就分享下我最近遇到的一个需求:

1、用户进行实名认证时将身份证的正反面照拍照上传(此功能无特别之处,合理也没难度)

2、对上传的图片进行解析,提取出页面需要展示的字段(问题应该不大)

自我感觉良好后,就着手干了,下面是我的实现过程:

首先到百度文字识别注册用户,生成你的ID,KEY,SECRET_KEY,地址:https://cloud.baidu.com/doc/OCR/s/rk3h7xzck

创建一个工具类:

public class BaiduApiUtil {

    //设置APPID/AK/SK
    private static String APP_ID = "16516516";
    private static String API_KEY ="XAxM8sp351651kv2IB";
    private static String SECRET_KEY = "tcENajuNu5116530368N9zIYGB";

    /**
     * 读取身份证正面照片信息
     *
     */
    public static JSONObject getFrontPicture(){

        // 初始化一个AipOcr
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);

        // 可选:设置网络连接参数
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);

        // 传入可选参数调用接口
        HashMap<String, String> options = new HashMap<String, String>();
        // 是否检测朝向
        options.put("detect_direction", "false");
        // 是否检测风险
        options.put("detect_risk", "false");

        //正反面front /back
        String idCardSide = "front";

        // 参数为本地图片路径
        String photoPath = "E://img//****.jpg";
        try {
            JSONObject res = client.idcard(photoPath, idCardSide, options);
            System.out.println(res.toString(2));
            if (res != null) {
                JSONObject wordsResult = res.getJSONObject("words_result");
                return wordsResult;
            } else {
                return null;
            }
        }catch (JSONException e){
            e.printStackTrace();
        }
        return null;
    }

}

当你兴致勃勃搞完准备接上业务逻辑时,发现这个方法有个很大的限制,它只能只能真的只能解析本地图片,当你配合阿里OSS用时,发现文件存储服务器返回的文件地址是无法直接解析的,这个就很痛苦了。。。。

至此,这个方法是行不通了,我换了个实现方式,现将前端上传的图片存到本地进行图片解析及上传阿里OSS,将上个方法稍作修改

public class BaiduApiUtil(String photoPath) {

    //设置APPID/AK/SK
    private static String APP_ID = "16516516";
    private static String API_KEY ="XAxM8sp351651kv2IB";
    private static String SECRET_KEY = "tcENajuNu5116530368N9zIYGB";

    /**
     * 读取身份证正面照片信息
     *
     */
    public static JSONObject getFrontPicture(){

        // 初始化一个AipOcr
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);

        // 可选:设置网络连接参数
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);

        // 传入可选参数调用接口
        HashMap<String, String> options = new HashMap<String, String>();
        // 是否检测朝向
        options.put("detect_direction", "false");
        // 是否检测风险
        options.put("detect_risk", "false");

        //正反面front /back
        String idCardSide = "front";

        // 参数为本地图片路径
        try {
            JSONObject res = client.idcard(photoPath, idCardSide, options);
            System.out.println(res.toString(2));
            if (res != null) {
                JSONObject wordsResult = res.getJSONObject("words_result");
                return wordsResult;
            } else {
                return null;
            }
        }catch (JSONException e){
            e.printStackTrace();
        }
        return null;
    }

}

解析及上传:

@Override
public String uploadPicture(MultipartFile file, String frontOrBack) {
    Map<String, Object> value = new HashMap<String, Object>();
    try {
        String url = upImgService.updateHead(file);
        System.out.println(url);
        value.put("url", url);
        value.put("code", 0);
        value.put("msg", "图片上传成功");
    } catch (Exception e) {
        value.put("code", 2000);
        value.put("msg", "图片上传失败");
    }

    if (file.isEmpty()){
        return "该文件是空的";
    }
    String filename = file.getOriginalFilename();
    String suffixName = filename.substring(filename.lastIndexOf("."));
    String filePath = "F://home//imgs//";
    filename = UUID.randomUUID() + suffixName;
    File dest = new File(filePath + filename);
    if (!dest.getParentFile().exists()) {
        dest.getParentFile().mkdirs();
    }
    try {
        file.transferTo(dest);
    } catch (IOException e) {
        e.printStackTrace();
    }
    String imgPath = filePath + filename;
    System.out.println(imgPath);
    if (frontOrBack.equals("front")){
        org.json.JSONObject frontPicture = BaiduApiUtil.getFrontPicture(imgPath);
        value.put("name", frontPicture.getJSONObject("姓名").get("words"));
        value.put("sex", frontPicture.getJSONObject("性别").get("words"));
        value.put("number", frontPicture.getJSONObject("公民身份号码").get("words"));

        return JSONObject.toJSONString(value);
    }else if (frontOrBack.equals("back")){
        org.json.JSONObject backPicture = BaiduApiUtil.getBackPicture(imgPath);
        value.put("usefulTime", backPicture.getJSONObject("失效日期").get("words"));
        return JSONObject.toJSONString(value);
    }
    return "";
}

Controller直接调用该方法即可,postman跑下接口,发现并没有问题,到此,身份图片上传+信息解析完美实现。

当然,还是希望阿里哪天能实现下图片上传+信息解析的功能。

Ps:如果文件上传量大的话,可以采用创建临时目录来实现,毕竟用完就可以删掉,也不必担心服务器内存问题了。

猜你喜欢

转载自blog.csdn.net/weixin_41146000/article/details/105813140