什么是OCR?
粗暴点说就是图片文本识别!正规点的说法就是:(Optical Character Recognition,光学电子识别)
最近公司开展新项目,考虑到实名认证这方面,然后还要上传身份证正反面,这就会涉及到一个问题,就是填写的身份证号,跟图片的身份证号对不上,或者我的图片是瞎上传的那种,那应该怎么办?
那只能使用图片文本识别就是所谓的OCR!
有很多种方法可以实现,比如人民币玩家的可以接第三方:聚合、阿里、腾讯.......等等众多平台都有相关的方案,
平民玩家的,也有插件:tesseract 但是需要FQ下载,我这两天翻不了墙,我就不试了,百度大把大把的教程,但是平民玩家会麻烦一点,这是肯定的,我思考了一下,还是用第三方的吧,简单粗暴点
我选择的是聚合数据OCR,https://www.juhe.cn/docs/api/id/287
步骤如下:
1)注册聚合数据账号
2)实名认证(我是拿公司的资料去认证的)
3)申请OCR(首次会有10次赠送)
4)获取图片转base64
5)请求一下接口就行了,就那么简单
直接上代码吧:
/**
* 获取网络图片
* @param imageUrl 图片URL
* @return
* @throws Exception
*/
public static String getURLImage(String imageUrl) throws Exception {
//new一个URL对象
URL url = new URL(imageUrl);
//打开链接
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为30秒
conn.setConnectTimeout(30 * 1000);
//通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(inStream);
// 转码
BASE64Encoder encode = new BASE64Encoder();
String s = encode.encode(data);
return s;
}
/**
* 已二进制去封装图片
* @param inStream 数据流
* @return
* @throws Exception
*/
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();
}
以上代码,是用于获取图片并且转成base64的
测试代码
public static void main(String[] args) throws Exception {
// 获取图片base64
String base64str = getURLImage("https://www.wobokeji.com/justgoFile/upload/image/1.jpg");
// System.out.println(base64str);
// 参数封装
NutMap map = new NutMap();
map.addv("key", "84f7e1be67db18c721fcfb0685720a11");
map.addv("image", base64str);
map.addv("side", "front");
// 请求聚合接口
String str = Http.post("http://apis.juhe.cn/idimage/verify", map, 20 * 1000);
System.out.println(str);
}
我用的框架是Nutz,这个框架都封装了一些Http请求的方法,我就直接拿来用了
看控制台打印,以下结果我都换了多张图片去测试,准确率满分,
注:昨晚就开始搞这个了,然后遇到了个异常,那时候没想出来是什么原因,就放了一下,回去之后,我在想,是不是转了base64之后就变成了200多万个字节的问题,是不是聚合那边不接受那么长的参数,如果不接收,那为什么需要转base64?后面仔细想了一下代码,猛地发现,是不是链接超时了?因为我的超时时间是 1000 毫秒,也就是 1 秒,那我想了一下,从我这里请求聚合 --》 聚合去识别这张图片并返回数据给我,这个过程需要多久?早上回来第一时间把连接时间改成20秒,然后整个世界都安静了,妈的,我就是个智障
还有一个点就是 转 base64 需要 sun.misc.base64decoder.jar 这个jar我找了一下,找不到maven的我就没照了,各位有人找到的话,给我留个言,哈哈哈哈