最近做者項目中用到了身份證識別跟營業執照的OCR識別,就研究了一下百度雲跟騰訊雲的OCR產品接口。html
1.騰訊雲OCR前端
收費:身份證OCR和營業執照OCR接口,每一個接口每一個月各有1000次的免費調用java
接口說明:json
身份證OCR接口 - 後端
https://cloud.tencent.com/document/product/866/33524api
https://cloud.tencent.com/document/product/866/17598app
身份證-OCR接入dom
引入騰訊的SDK及JSONide
<dependency> <groupId>com.tencentcloudapi</groupId> <artifactId>tencentcloud-sdk-java</artifactId> <version>3.0.58</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency>
2.前端html代碼
<form action="/ocr/uploadFile" method="POST" enctype="multipart/form-data"> <input type="file" name="file"> <br /> <input type="radio" name="card_side" value="FRONT"> 正面 <input type="radio" name="card_side" value="BACK"> 反面 <br /> <input type="submit" value="提交"> </form>
3.後端代碼
@PostMapping("uploadFile") @ResponseBody public IDCardOCRResponse OCRIdCardTest(@RequestParam(value = "file") MultipartFile file,@RequestParam(value = "card_side") String cardSize,Model model){ try { Credential cred = new Credential("AKIDGQfhYTqEs0DMvUQH93wXKsIX", "7adThzEEH6mK6zg9MMwX0"); HttpProfile httpProfile = new HttpProfile(); httpProfile.setEndpoint("ocr.tencentcloudapi.com"); ClientProfile clientProfile = new ClientProfile(); clientProfile.setHttpProfile(httpProfile); OcrClient client = new OcrClient(cred, "ap-beijing", clientProfile); Map<String, String> params = new HashMap<>(); params.put("ImageBase64", getBase64FromInputStream(file.getInputStream())); params.put("CardSide", cardSize); System.out.println(getBase64FromInputStream(file.getInputStream())); IDCardOCRRequest req = IDCardOCRRequest.fromJsonString(JSONObject.fromObject(params).toString(), IDCardOCRRequest.class); IDCardOCRResponse resp = client.IDCardOCR(req); return resp; } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return null; }
說明:new Credential("secretId","secretKey"),這兩個參數在騰訊雲控制檯申請
4.getBase64FromInputStream代碼,把MultipartFile 轉爲base64
public static String getBase64FromInputStream(InputStream in) { // 將圖片文件轉化爲字節數組字符串,並對其進行Base64編碼處理 byte[] data = null; // 讀取圖片字節數組 try { ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[100]; int rc = 0; while ((rc = in.read(buff, 0, 100)) > 0) { swapStream.write(buff, 0, rc); } data = swapStream.toByteArray(); } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return new String(Base64.encodeBase64(data)); }
運行前端html碼,選擇身份證圖片,點擊提交就能夠返回身份證的信息了。
營業執照-OCR
1.前端html代碼
<form action="/ocr/bizlicense" method="POST" enctype="multipart/form-data"> <input type="file" name="file"> <br /> <input type="submit" value="提交"> </form>
2.後端代碼
@PostMapping("bizlicense") @ResponseBody public String OCRBizlicenseTest(@RequestParam(value = "file") MultipartFile file) throws Exception{ RestTemplate restTemplate = new RestTemplate(); String apiUrl="https://recognition.image.myqcloud.com/ocr/bizlicense"; HttpHeaders headers = new HttpHeaders(); headers.set("host", "recognition.image.myqcloud.com"); headers.set("content-type", "application/json"); String authorization=QQOCRSignUtils.appSign(XXXX, "AKIDGQfhYTqEs0DXXX", "7adThzEEH6mKXXX", "", 10L); headers.set("authorization",authorization ); JSONObject params = new JSONObject(); params.put("appid", "XXX"); params.put("image", getBase64FromInputStream(file.getInputStream())); HttpEntity<JSONObject> entity = new HttpEntity<JSONObject>(params, headers); HttpEntity<String> response = restTemplate.postForEntity(apiUrl, entity, String.class); return response.getBody(); }
3.QQOCRSignUtils.appSign
/** * 生成 Authorization 簽名字段 * * @param appId * @param secretId * @param secretKey * @param bucketName * @param expired * @return * @throws Exception */ public static String appSign(long appId, String secretId, String secretKey, String bucketName, long expired) throws Exception { long now = System.currentTimeMillis() / 1000; int rdm = Math.abs(new Random().nextInt()); String plainText = String.format("a=%d&b=%s&k=%s&t=%d&e=%d&r=%d", appId, bucketName, secretId, now, now + expired, rdm); byte[] hmacDigest = HmacSha1(plainText, secretKey); byte[] signContent = new byte[hmacDigest.length + plainText.getBytes().length]; System.arraycopy(hmacDigest, 0, signContent, 0, hmacDigest.length); System.arraycopy(plainText.getBytes(), 0, signContent, hmacDigest.length, plainText.getBytes().length); return Base64Encode(signContent); }
運行前端html碼,選擇營業執照圖片,點擊提交就能夠返回營業執照的信息了。
2.百度OCR
經過如下步驟建立OCR應用,做者當時在這一步花了很長時間
建立完以後就能夠拿到appId,API Key,Secret Key,就能夠調用百度提供的api了
收費:身份證OCR和營業執照OCR接口,每一個接口天天各有500次的免費調用
接口說明:
身份證OCR接口 -
https://cloud.baidu.com/doc/OCR/OCR-API.html#.E8.BA.AB.E4.BB.BD.E8.AF.81.E8.AF.86.E5.88.AB
https://cloud.baidu.com/doc/OCR/OCR-API.html#.E8.90.A5.E4.B8.9A.E6.89.A7.E7.85.A7.E8.AF.86.E5.88.AB
身份證OCR
只列出後端的代碼,前端代碼跟騰訊的同樣,只不過先後面身份證枚舉值不同,參考接口文檔說明。
@PostMapping("ocridcard") @ResponseBody public String OCRIdCardTest(@RequestParam(value = "file") MultipartFile file,@RequestParam(value = "card_side") String cardSize,Model model){ try { RestTemplate restTemplate = new RestTemplate(); HttpEntity<String> response = restTemplate.postForEntity("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=XXXXXX&client_secret=XXXXXX",null,String.class); JSONObject jsonObject = JSONObject.fromObject(response.getBody()); System.out.println(response.getBody()); String accessToken = jsonObject.getString("access_token"); String apiUrl="https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token="+accessToken; HttpHeaders headers = new HttpHeaders(); headers.set("content-type", "application/x-www-form-urlencoded"); MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); params.add("detect_direction", "true"); params.add("id_card_side", cardSize); params.add("image", Base64Utils.getBase64FromInputStream(file.getInputStream())); params.add("detect_risk", "true"); System.out.println(Base64Utils.getBase64FromInputStream(file.getInputStream())); System.out.println(URLDecoder.decode(URLEncoder.encode(Base64Utils.getBase64FromInputStream(file.getInputStream()),"UTF-8"),"UTF-8")); HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(params, headers); response = restTemplate.postForEntity(apiUrl, entity, String.class); return response.getBody(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return null; }
營業執照OCR
@PostMapping("ocrbusinesslicense") @ResponseBody public String OCRBusinessLicenseTest(@RequestParam(value = "file") MultipartFile file,Model model){ try { RestTemplate restTemplate = new RestTemplate(); HttpEntity<String> response = restTemplate.postForEntity("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=XXXXX&client_secret=XXXXXX",null,String.class); JSONObject jsonObject = JSONObject.fromObject(response.getBody()); System.out.println(response.getBody()); String accessToken = jsonObject.getString("access_token"); String apiUrl="https://aip.baidubce.com/rest/2.0/ocr/v1/business_license?access_token="+accessToken; HttpHeaders headers = new HttpHeaders(); headers.set("content-type", "application/x-www-form-urlencoded"); MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); params.add("detect_direction", "true"); params.add("image", Base64Utils.getBase64FromInputStream(file.getInputStream())); System.out.println(Base64Utils.getBase64FromInputStream(file.getInputStream())); System.out.println(URLDecoder.decode(URLEncoder.encode(Base64Utils.getBase64FromInputStream(file.getInputStream()),"UTF-8"),"UTF-8")); HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(params, headers); response = restTemplate.postForEntity(apiUrl, entity, String.class); return response.getBody(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return null; }