核心代码如下
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工具
/**
* 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();
}
}
}