失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > SpringBoot Vue对接百度云API实现身份证信息识别功能(超详细 包含具体代码实现)

SpringBoot Vue对接百度云API实现身份证信息识别功能(超详细 包含具体代码实现)

时间:2022-10-04 08:02:57

相关推荐

SpringBoot Vue对接百度云API实现身份证信息识别功能(超详细 包含具体代码实现)

记录一次开发过程中,Springboot、vue、oss文件上传的整合框架,对接百度云卡证识别API实现身份证信息识别功能的详细过程,包含具体代码实现以及详细注释。

文章目录

前提知识1.JSON2.JSONObject3.JSONArray4.JSONObject、JSONArray的用法 一.官网参照二.实现方式三.参照文档四.代码实现4.1.对接接口处理包4.1.1.AuthToken.java—token获取4.1.2.HttpUtil—HTTP请求工具类4.1.3.FileUtil.java—读取身份证文件工具类4.1.4.GsonUtils.java—Gson工具类4.1.5 IdCardUtil—接口调用调试,读取信息4.1.6.图片转base644.1.7.处理返回的JSON数据 4.2.功能实现代码4.2.1.接口请求api4.2.2.vue页面4.2.3controller层

前提知识

由于对接第三方API时涉及到JSON格式化处理,需要提前熟悉以下内容,方便前后端数据交互。

1.JSON

轻量级的数据交换格式,常用于前后端数据交互。(key-value形式的数据结构)

2.JSONObject

JSON对象,由{}将多个属性包括起来。

{"key":"value","key":"value","key":"value","key":"value","key":"value"}

3.JSONArray

JSON数组,由[]将多个jsonobject包括起来。

[{"key":"value","key":"value","key":"value","key":"value","key":"value"},{"key":"value","key":"value","key":"value","key":"value","key":"value"}]

4.JSONObject、JSONArray的用法

//1.JSON字符串转为JSONObject、指定的实体类String result="json字符串";JSONObject jsonObject=JSON.parseObject(result);IdCardBean idCardBean=JSON.parseObject(result,IdCardBean.class)//2.JSONObject中取出指定的JSONArrayJSONArray words_result=jsonObject.getJSONArray("words_result");//3.JSONArray中取出JSONObject,i为数组下标JSONObject card_front= (JSONObject) words_result.get(i);//4.取出JSONObject中的key值String keyValue=jsonObject.getString(i);

一.官网参照

卡证文字识别_证件文字识别_银行卡身份证文字识别-百度AI开放平台

二.实现方式

基于百度智能云卡证识别(混贴识别) ,身份证正反面在同一图片上。

三.参照文档

文字识别OCR

四.代码实现

需要引入依赖包

<dependency><groupId>com.baidu.aip</groupId><artifactId>java-sdk</artifactId><version>4.16.12</version></dependency>

4.1.对接接口处理包

4.1.1.AuthToken.java—token获取

package org.springblade.modules.tendering.baiduapi;/*** @author * @date /10/15 14:53* @description*/import org.json.JSONObject;import java.io.BufferedReader;import java.io.InputStreamReader;import .HttpURLConnection;import .URL;import java.util.List;import java.util.Map;/*** 获取token类*/public class AuthToken {/*** 获取权限token* @return 返回示例:* {* "access_token": ,* "expires_in": 2592000* }*/public static String getAuth() {// 官网获取的 API Key 更新为你注册的String clientId = "";// 官网获取的 Secret Key 更新为你注册的String clientSecret = "";return getAuth(clientId, clientSecret);}/*** 获取API访问token* 该token有一定的有效期,需要自行管理,当失效时需重新获取.* @param ak - 百度云官网获取的 API Key* @param sk - 百度云官网获取的 Secret Key* @return assess_token 示例:* ""*/public static String getAuth(String ak, String sk) {// 获取token地址String authHost = "/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<String, List<String>> 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");return access_token;} catch (Exception e) {System.err.printf("获取token失败!");e.printStackTrace(System.err);}return null;}}

4.1.2.HttpUtil—HTTP请求工具类

package org.springblade.modules.tendering.baiduapi;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.InputStreamReader;import .HttpURLConnection;import .URL;import java.util.List;import java.util.Map;/*** http 工具类*/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<String, List<String>> 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;}}

4.1.3.FileUtil.java—读取身份证文件工具类

package org.springblade.modules.tendering.baiduapi;import java.io.*;/*** 文件读取工具类*/public class FileUtil {/*** 读取文件内容,作为字符串返回*/public static String readFileAsString(String filePath) throws IOException {File file = new File(filePath);if (!file.exists()) {throw new FileNotFoundException(filePath);}if (file.length() > 1024 * 1024 * 1024) {throw new IOException("File is too large");}StringBuilder sb = new StringBuilder((int) (file.length()));// 创建字节输入流FileInputStream fis = new FileInputStream(filePath);// 创建一个长度为10240的Bufferbyte[] bbuf = new byte[10240];// 用于保存实际读取的字节数int hasRead = 0;while ( (hasRead = fis.read(bbuf)) > 0 ) {sb.append(new String(bbuf, 0, hasRead));}fis.close();return sb.toString();}/*** 根据文件路径读取byte[] 数组*/public static byte[] readFileByBytes(String filePath) throws IOException {File file = new File(filePath);if (!file.exists()) {throw new FileNotFoundException(filePath);} else {ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());BufferedInputStream in = null;try {in = new BufferedInputStream(new FileInputStream(file));short bufSize = 1024;byte[] buffer = new byte[bufSize];int len1;while (-1 != (len1 = in.read(buffer, 0, bufSize))) {bos.write(buffer, 0, len1);}byte[] var7 = bos.toByteArray();return var7;} finally {try {if (in != null) {in.close();}} catch (IOException var14) {var14.printStackTrace();}bos.close();}}}}

4.1.4.GsonUtils.java—Gson工具类

/** Copyright (C) Baidu, Inc. All Rights Reserved.*/package org.springblade.modules.tendering.baiduapi;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.google.gson.JsonParseException;import java.lang.reflect.Type;import java.util.HashMap;import java.util.Iterator;/*** Json工具类.*/public class GsonUtils {private static Gson gson = new GsonBuilder().create();public static String toJson(Object value) {return gson.toJson(value);}public static <T> T fromJson(String json, Class<T> classOfT) throws JsonParseException {return gson.fromJson(json, classOfT);}public static <T> T fromJson(String json, Type typeOfT) throws JsonParseException {return (T) gson.fromJson(json, typeOfT);}}

4.1.5 IdCardUtil—接口调用调试,读取信息

package org.springblade.modules.tendering.baiduapi;/*** @author zhenshouen* @date /10/27 9:12* @description*/import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.baidu.aip.util.Base64Util;import com.google.gson.Gson;import com.google.gson.JsonArray;import com.google.gson.JsonObject;import org.springblade.modules.tendering.entity.IdCard;import .URLEncoder;import java.util.HashMap;import java.util.Iterator;/*** 身份证混贴识别*/public class IdCardUtil {/*** 重要提示代码中所需工具类* FileUtil,Base64Util,HttpUtil,GsonUtils请从* /file/658A35ABAB2D404FBF903F64D47C1F72* /file/C8D81F3301E24D2892968F09AE1AD6E2* /file/544D677F5D4E4F17B4122FBD60DB82B3* /file/470B3ACCA3FE43788B5A963BF0B625F3* 下载*/public static String idcard() {// 请求urlString url = "/rest/2.0/ocr/v1/multi_idcard";try {// 本地文件路径String filePath = "D:/身份证.jpg";byte[] imgData = FileUtil.readFileByBytes(filePath);System.out.println("imgData:" + imgData);String imgStr = Base64Util.encode(imgData);String imgParam = URLEncoder.encode(imgStr, "UTF-8");String param = "image=" + imgParam;// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。String accessToken = AuthToken.getAuth();String result = HttpUtil.post(url, accessToken, param);return result;} catch (Exception e) {e.printStackTrace();}return null;}public static void main(String[] args) {IdCardUtil.idcard();}}

4.1.6.图片转base64

包含本地路径图片以及URL资源图片转换为base64的两种方法。

import mons.codec.binary.Base64;import sun.misc.BASE64Encoder;import java.io.*;import .HttpURLConnection;import .URL;/*** @author zhenshouen* @date /11/17 15:30* @description 网络url图片转为base64*/public class ImgToBase64 {public static void main(String[] args) throws Exception {//对网络地址图片做测试String url="http://127.0.0.1:9000/bid/upload/1117/68d0dd7c6f71f623787fb837fca53846.jpg";String a = ImgToBase64.getBase64ByUrl(url);System.out.println(a);}/*** 根据图片链接转为base64数据** @param imageUrl* @return* @throws Exception*/public static String getBase64ByUrl(String imageUrl) throws Exception {// new一个URL对象URL url = new URL(imageUrl);// 打开链接HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 设置请求方式为"GET"conn.setRequestMethod("GET");// 超时响应时间为5秒conn.setConnectTimeout(5 * 1000);// 通过输入流获取图片数据InputStream inStream = conn.getInputStream();// 得到图片的二进制数据,以二进制封装得到数据,具有通用性byte[] data = readInputStream(inStream);BASE64Encoder encode = new BASE64Encoder();String s = encode.encode(data);return s;}private static byte[] readInputStream(InputStream inStream) throws Exception {ByteArrayOutputStream outStream = new ByteArrayOutputStream();// 创建一个Buffer字符串byte[] buffer = new byte[1024];// 每次读取的字符串长度,如果为-1,代表全部读取完毕int len = 0;// 使用一个输入流从buffer里把数据读取出来while ((len = inStream.read(buffer)) != -1) {// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度outStream.write(buffer, 0, len);}// 关闭输入流inStream.close();// 把outStream里的数据写入内存return outStream.toByteArray();}/*** @Description: 将图片转换成base64编码的字符串* @param @param imageSrc 文件路径* @param @return* @return String* @throws IOException*/public static String imageToBase64(String imageSrc) throws IOException {//判断文件是否存在File file=new File(imageSrc);if(!file.exists()){throw new FileNotFoundException("文件不存在!");}StringBuilder pictureBuffer = new StringBuilder();FileInputStream input=new FileInputStream(file);ByteArrayOutputStream out = new ByteArrayOutputStream();//读取文件Base64 base64=new Base64();byte[] temp = new byte[1024];for(int len = input.read(temp); len != -1;len = input.read(temp)){out.write(temp, 0, len);}pictureBuffer.append(new String( base64.encodeBase64Chunked(out.toByteArray())));input.close();return pictureBuffer.toString();}}

4.1.7.处理返回的JSON数据

一层一层提取出各个类。

//调用第三方接口,获取到的结果,需要格式化处理json数据。{"words_result":[{"card_info":{"card_location":{"top":330,"left":707,"width":1038,"height":647},"card_type":"idcard_front","direction":0,"idcard_number_type":1,"image_status":"normal"},"card_result":{"姓名":{"location":{"top":404,"left":921,"width":137,"height":51},"words":"张三"},"民族":{"location":{"top":489,"left":1127,"width":37,"height":44},"words":"汉"},"住址":{"location":{"top":640,"left":918,"width":405,"height":107},"words":"河北省XXXXXXXXXXXXXX"},"公民身份号码":{"location":{"top":835,"left":1075,"width":549,"height":68},"words":"64654653313485624"},"出生":{"location":{"top":560,"left":928,"width":320,"height":53},"words":"19980511"},"性别":{"location":{"top":489,"left":930,"width":41,"height":42},"words":"男"}}},{"card_info":{"card_location":{"top":1092,"left":693,"width":1043,"height":671},"card_type":"idcard_back","direction":0,"image_status":"normal"},"card_result":{"失效日期":{"location":{"top":1627,"left":1354,"width":193,"height":56},"words":"20290131"},"签发机关":{"location":{"top":1546,"left":1149,"width":176,"height":54},"words":"XX公安局"},"签发日期":{"location":{"top":1628,"left":1149,"width":190,"height":56},"words":"0131"}}}],"log_id":1592688515663812000}//从外由里,依次提取为实体类,[]代表数组,{}代表一个类对象public class WordsResult {private CardInfo cardInfo;private CardResult cardResult;}public class CardInfo {private CardLocation cardLocation;private String cardType;private int direction;private int idCardNumberType;private String imageStatus;}//@JSONField用于为json中的key取别名,因为百度返回的是中文,所以要更改为英文变量名public class CardResult {@JSONField(name="住址")private Address address;@JSONField(name="出生")private Birth birth;@JSONField(name="姓名")private Name name;@JSONField(name="公民身份号码")private IdCardNum idCardNum;@JSONField(name="性别")private Sex sex;@JSONField(name="民族")private Nation nation;@JSONField(name="签发日期")private IssueDate issueDate;@JSONField(name="签发机关")private Authority authority;@JSONField(name="失效日期")private ExpiryDate expiryDate;}public class CardLocation {private int top;private int left;private int width;private int height;}public class Location {private int top;private int left;private int width;private int height;}public class Name {private Location location;private String words;}public class Nation {private Location location;private String words;}public class Sex {private Location location;private String words;}public class IssueDate {private Location location;private String words;}public class IdCardNum {private Location location;private String words;}public class IdCardBean {private Long log_id;private List<WordsResult> wordsResult;}public class ExpiryDate {private Location location;private String words;}public class Birth {private Location location;private String words;}public class Authority {private Location location;private String words;}public class Address {private Location location;private String words;}

4.2.功能实现代码

4.2.1.接口请求api

封装的统一前端接口地址,也可以直接放到实现功能的vue页面。

export const getIdCardInfo = (imgUrl) => {return request({url: '/api/blade-IdCard/IdCard/getCardInfo',method: 'get',params: {imgUrl,}})}

4.2.2.vue页面

先对图片的地址做一下处理,因上传后的地址为"/oss/…jpg",这里要对oss替换成网络地址,之后调取接口即可。

<el-button type="primary" :size="size" @click="tell()">信息识别</el-button>tell(){var imgUrl=this.form.idCard.replace("/oss","http://127.0.0.1:9000");getIdCardInfo(imgUrl).then((res)=>{if(res.data.code==200){this.$message({type: "success",message:"提取成功"})//回填到页面显示框this.form.name=res.data.data.name;this.form.sex=res.data.data.sex;this.form.birthday=res.data.data.birthday;this.form.nation=res.data.data.nation;this.form.idNumber=res.data.data.idNumber;this.form.issuedOrganization=res.data.data.issuedOrganization;this.form.issuedDate=res.data.data.issuedDate;this.form.expirDate=res.data.data.expirDate;this.form.address=res.data.data.address;}});},

4.2.3controller层

imgUrl入参为上传的身份证图片的网络地址(图片上传到了OSS),需要对网络地址形式的图片转换Base64编码。

/*** 获取身份证信息imgUrl为图片的网络地址,*/@GetMapping("/getCardInfo")public R<IdCard> getCardInfo(String imgUrl){try {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyymmdd");simpleDateFormat.setLenient(false);String url = "/rest/2.0/ocr/v1/multi_idcard";String imgStr = ImgToBase64.getBase64ByUrl(imgUrl);String imgParam = URLEncoder.encode(imgStr, "UTF-8");String param = "image=" + imgParam;String accessToken = AuthToken.getAuth();IdCard idCard = new IdCard();//调用百度卡证识别API接口IdCardBean idCardBean = JSON.parseObject(HttpUtil.post(url, accessToken, param), IdCardBean.class);//可以放到map集合中,下方代码有利于新手理解String name=idCardBean.getWordsResult().get(0).getCardResult().getName().getWords();String address=idCardBean.getWordsResult().get(0).getCardResult().getAddress().getWords();String sex=idCardBean.getWordsResult().get(0).getCardResult().getSex().getWords();String birth=idCardBean.getWordsResult().get(0).getCardResult().getBirth().getWords();String idCardNum=idCardBean.getWordsResult().get(0).getCardResult().getIdCardNum().getWords();String nation=idCardBean.getWordsResult().get(0).getCardResult().getNation().getWords();String issuedOrganiz=idCardBean.getWordsResult().get(1).getCardResult().getAuthority().getWords();String issueDateStr=idCardBean.getWordsResult().get(1).getCardResult().getIssueDate().getWords();String expirDateStr=idCardBean.getWordsResult().get(1).getCardResult().getExpiryDate().getWords();Date birthday = simpleDateFormat.parse(birth);Date expirDate= simpleDateFormat.parse(expirDateStr);Date issueDate=simpleDateFormat.parse(issueDateStr);//取出值后放到idCard中idCard.setName(name);idCard.setBirthday(birthday);idCard.setAddress(address);idCard.setSex(sex);idCard.setExpirDate(expirDate);idCard.setIdNumber(idCardNum);idCard.setIssuedDate(issueDate);idCard.setIssuedOrganization(issuedOrganiz);idCard.setNation(nation);idCard.setIsDeleted(0);return R.data(200,idCard,"提取成功");}catch (Exception e){e.printStackTrace();}return R.fail("提取失败");}

如果觉得《SpringBoot Vue对接百度云API实现身份证信息识别功能(超详细 包含具体代码实现)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。