Android
本地OCR
识别, 网上流行的基本上都是tesstwo
实现的, 大家可以百度一下.
鉴于识别效率和体验, 种种原因…
云识别也是需要了解一下的:
大厂的SDK
文档都很详细, 这里把简单的使用入门放在一起, 大家可以参考一下:
注意: 百度和讯飞 免费接口 一天只能请求500次, 云识别 未知…
SSL
由于大厂使用了https
的接口链接, 如果直接用OkHttp
请求, 会报错. 需要配置一下即可:
/**
* Https SSL安全验证
*/
public static OkHttpClient.Builder noSSL(OkHttpClient.Builder builder) {
X509TrustManager x509TrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
final TrustManager[] trustAllCerts = new TrustManager[]{x509TrustManager};
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting trust manager
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
builder.sslSocketFactory(sslContext.getSocketFactory(), x509TrustManager);
builder.hostnameVerifier(hostnameVerifier);
} catch (Exception e) {
e.printStackTrace();
}
return builder;
}
百度OCR
使用百度接口之前, 需要先调用一个获取Token
的接口. 再使用返回的token
, 请求其他接口.
private void getToken() {
if (token == null) {
final Request request = new Request.Builder()
.url("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" +
API_KEY + "&client_secret=" + SECRET_KEY)
.post(RequestBody.create(MediaType.parse("application/json"), ""))
.build();
requestIng.set(true);
//获取Token
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
requestIng.set(false);
try {
String body = response.body().string();
JSONObject jsonObject = new JSONObject(body);
token = jsonObject.getString("access_token");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
OCR 接口
/**
* 百度ocr
*/
public void ocrBaidu(byte[] bytes) {
if (bytes != null && !requestIng.get() && !TextUtils.isEmpty(token)) {
String body = null;
try {
body = "image=" + URLEncoder.encode(Base64.encodeToString(bytes, Base64.NO_WRAP), "UTF8") +
"&id_card_side=front";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
final Request request = new Request.Builder()
.url("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + token)
.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), body))
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
requestIng.set(false);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
requestIng.set(false);
try {
String body = response.body().string();
JSONObject jsonObject = new JSONObject(body);
String words = jsonObject.getJSONObject("words_result").getJSONObject("公民身份证号码").getString("words");
//L.i("识别结果:"+ words);
if (onResultCallback != null) {
onResultCallback.onResult(null, null, words);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
讯飞OCR
讯飞的接口, 可以直接调用, 但是参数封装比较麻烦:
public void ocrXf(byte[] bytes) {
if (bytes != null && !requestIng.get()) {
final String key = "key";
final String curTime = String.valueOf(System.currentTimeMillis() / 1000);
String body = null;
try {
body = "image=" + URLEncoder.encode(Base64.encodeToString(bytes, Base64.NO_WRAP), "UTF8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String param = Json.json()
.add("engine_type", "idcard")
.get();
param = Base64.encodeToString(param.getBytes(), Base64.NO_WRAP);
final Request request = new Request.Builder()
.url("https://webapi.xfyun.cn/v1/service/v1/ocr/idcard")
.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), body))
.addHeader("X-Appid", "5cc2c404")
.addHeader("X-CurTime", curTime)
.addHeader("X-Param", param)
.addHeader("X-CheckSum", RUtils.md5(key + curTime + param))
.build();
requestIng.set(true);
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
requestIng.set(false);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
requestIng.set(false);
try {
String body = response.body().string();
JSONObject jsonObject = new JSONObject(body);
String words = jsonObject.getJSONObject("data").getString("id_number");
if (onResultCallback != null) {
onResultCallback.onResult(null, null, words);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
图片基本上都需要进行Base64
处理.
其他厂家
这个是非公开接口, 返回数据也是非json
格式. 仅供参考
public void ocrOther(byte[] bytes) {
if (bytes != null && !requestIng.get()) {
//构造上传请求,类似web表单
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addPart(Headers.of("Content-Disposition", "form-data; name=\"callbackurl\""), RequestBody.create(null, "/idcard/"))
.addPart(Headers.of("Content-Disposition", "form-data; name=\"action\""), RequestBody.create(null, "idcard"))
.addPart(Headers.of("Content-Disposition", "form-data; name=\"img\"; filename=\"idcardFront_user.jpg\""), RequestBody.create(MediaType.parse("image/jpeg"), bytes))
.build();
//进行包装,使其支持进度回调
final Request request = new Request.Builder()
.header("Host", "ocr.ccyunmai.com:8080")
.header("Origin", "http://ocr.ccyunmai.com:8080")
.header("Referer", "http://ocr.ccyunmai.com:8080/idcard/")
.header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2398.0 Safari/537.36")
.url("http://ocr.ccyunmai.com:8080/UploadImage.action")
.post(requestBody)
.build();
requestIng.set(true);
//开始请求
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
if (e instanceof UnknownHostException) {
} else {
requestIng.set(false);
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
requestIng.set(false);
try {
final String result = response.body().string();
Matcher matcher = Pattern.compile(ID_PATTERN).matcher(result);
while (matcher.find()) {
Log.i("识别结果1:", matcher.group(0));
Log.i("识别结果2:", matcher.group());
}
} catch (Exception e) {
e.printStackTrace();
}
// Document parse = Jsoup.parse(result);
// final Elements select = parse.select("div#ocrresult");
// Log.e(TAG, "onResponse: " + select.text());
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
// tv_result.setText(getHtmlMsg(select.text(), "公民身份号码:", "签发机关"));
// }
// });
}
});
}
}
群内有各(pian)种(ni)各(jin)样(qun)
的大佬,等你来撩.
联系作者
请使用QQ扫码加群, 小伙伴们都在等着你哦!
关注我的公众号, 每天都能一起玩耍哦!