概括:
实现的功能是微信小程序调用手机摄像头或者上传本地照片进行身份证识别。身份证识别调用的是百度云API,具体操作见下面的教程。
一:百度云api使用
1:百度云新建应用
具体操作按照下面的图片进行操作:
(1)产品->人工智能->卡证文字识别
(2)立即使用
(3)创建应用
(4)更具提示点击创建应用
(5)查看ak和sk
(6)领取免费资源
二:微信小程序实现身份证拍照和本地上传身份证
wxxml
js
调用摄像头拍照
//调用微信摄像机
call_camera: function(){
var _this = this;
_this.setData({
topNum: 0,
show_condition: false,
});
},
//微信摄像机 拍照
take_photo: function(){
var _this = this;
_this.ctx.takePhoto({
quality: 'high',
success:function(res){
var url=res.tempImagePath
console.log("url:"+url)
_this.setData({
//返回的是单张
tempFilePaths: res.tempImagePath,
show_condition: true,
});
_this.show_msg('正在上传', 'loading');
//图片上传
wx.uploadFile({
url: 'http://localhost:8080/car/ocr/dealpicture',
filePath: res.tempImagePath,
name: 'file',
success: function (res) {
console.log("succ")
// var s=res.data
// console.log(s)
// var s1=s.length-2
// var rs=s.slice(9,s1)
// console.log(rs)
// wx.setStorageSync("picturepath", rs)
},
fail: function (err) {
console.log(err.data)
}
})
},
})
},
本地照片选择
//相册中选择图像向服务器发送数据 可选:拍照
choose_photo: function() {
var _this = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album'],
success: function(res) {
_this.setData({
//返回的是文件列表 如果是一张的话 要取第一张
tempFilePaths: res.tempFilePaths[0]
});
_this.show_msg('正在解析', 'loading');
console.log("大小"+res.tempFiles[0].size)
var picsize=res.tempFiles[0].size
if(picsize>=2000000){
wx.showToast({
title: '照片大小超过2M',
icon: 'none',
duration: 4000
})
}else{
//图片上传
wx.uploadFile({
url: 'http://localhost:8080/car/ocr/dealpicture',
filePath: res.tempFilePaths[0],
name: 'file',
success: function (res) {
console.log("数据:"+res.data.mess)
},
fail: function (err) {
console.log(err.data)
}
})
}
}
});
},
三、后台实现身份证识别
小程序调用后台接口地址:(拍照和本地上传都是同一个接口)
url: ‘http://localhost:8080/car/ocr/dealpicture’,
整体实现思路
后台接受图片->调用百度api(调用百度api之前要实现图片bas64位编码和获取token)
(1)接受微信传来的图片和调用iccar()方法
//接受微信小程序传过来的图片 同时完成照片的识别
@RequestMapping("dealpicture")
@ResponseBody
public JSonObject dealpicture(MultipartFile file, HttpServletRequest request) throws IOException {
ocrController test=new ocrController();
Map map=new HashMap();
//照片输出路径
String dir = "D:\pic";
System.out.println("输出文件的路径"+dir);
// //String filePath = "E:\upload";//保存图片的路径
//获取原始图片的拓展名
String originalFilename = file.getOriginalFilename();
String picadd=dir+"\"+originalFilename;
//新的文件名字
System.out.println(picadd);
//String newFileName = UUID.randomUUID()+originalFilename;
//封装上传文件位置的全路径
File targetFile = new File(dir,originalFilename);
// BufferedImage sourceImg = ImageIO.read(new FileInputStream(targetFile));
// System.out.println(String.format("%.1f",targetFile.length()/1024.0));
//文件的路径不存在 创建
if (!targetFile.exists()){
targetFile.mkdirs();
}
file.transferTo(targetFile);//把本地文件上传到封装上传文件位置的全路径
// map.put("mess", newFileName);
// JSonObject json=JSONObject.fromObject(map);
JSonObject mess= test.iccar(picadd);
return mess;
}
(2)调用身份识别request方法 解析返回的数据 放入map中
//身份证识别 去百度接口调用api 完成识别 解析返回来的信息
public JSonObject iccar(String picadd){
//获取本地的绝对路径图片
File file = new File(picadd);
System.out.println("照片输出"+file);
ocrController test=new ocrController();
//进行base64位编码
String imagebase = test.encodeImgageTobase64(file);
imagebase = imagebase.replaceAll("rn","");
imagebase = imagebase.replaceAll("\+","%2B");
//获取token
String tok=test.getAuth();
//百度云的文字识别接口,后面参数为获取到的token
String httpUrl=" https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token="+tok;
String httpArg = "detect_direction=true&id_card_side=front&image="+imagebase;
String jsonResult = request(httpUrl, httpArg);
System.out.println("返回的结果--------->"+jsonResult);
//转化为json
JSonObject jsonObject = JSONObject.parseObject(jsonResult).getJSonObject("words_result");
System.out.println("返回的结果--------->"+jsonObject);
Map maps = (Map) JSON.parse(jsonObject.getString("姓名"));
System.out.println("姓名:"+maps.get("words"));
Map maps1 = (Map) JSON.parse(jsonObject.getString("民族"));
System.out.println("民族:"+maps1.get("words"));
Map maps2 = (Map) JSON.parse(jsonObject.getString("住址"));
System.out.println("住址:"+maps2.get("words"));
Map maps3 = (Map) JSON.parse(jsonObject.getString("公民身份号码"));
System.out.println("身份证号码:"+maps3.get("words"));
HashMap map = new HashMap();
map.put("name",maps.get("words"));
map.put("nation",maps1.get("words"));
map.put("add",maps2.get("words"));
map.put("idnum",maps3.get("words"));
// Map 转 json string
String jsonStr = JSONObject.toJSonString( map );
// 将 json string 转化为 JSonObject
JSonObject obj = JSONObject.parseObject( jsonStr );
return obj;
//System.out.println(obj);
}
(3)获取token
需要官网的ak和sk
//获取token
public String getAuth() {
String ak="官网的ak";
String sk="官网的sk";
// 获取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
// 1. grant_type为固定参数2. 官网获取的 API Key 3. 官网获取的 Secret Key
String getAccessTokenUrl = authHost+ "grant_type=client_credentials" + "&client_id=" + ak + "&client_secret=" + sk;
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("POST");//百度推荐使用POST请求
connection.connect();
// 获取所有响应头字段
Map> map = connection.getHeaderFields();
// 定义 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);
JSonObject jsonObject = JSONObject.parseObject(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)将图片进行bas64编码
//将图片进行bas64编码
public static String encodeImgageTobase64(File imageFile) {
// 将图片文件转化为字节数组字符串,并对其进行base64编码处理
// 其进行base64编码处理
byte[] data = null;
// 读取图片字节数组
try {
InputStream in = new FileInputStream(imageFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
// 对字节数组base64编码
base64Encoder encoder = new base64Encoder();
return encoder.encode(data);// 返回base64编码过的字节数组字符串
}
(5)调用百度识别API
//身份证识别
public static String request(String httpUrl, String httpArg) {
ocrController test=new ocrController();
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
try {
//用java JDK自带的URL去请求
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置该请求的消息头
//设置HTTP方法:POST
connection.setRequestMethod("POST");
//设置其Header的Content-Type参数为application/x-www-form-urlencoded
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
// 填入apikey到HTTP header
connection.setRequestProperty("apikey", "SyvTwGgyAXehhh69poSZ7Dg8");
//将第二步获取到的token填入到HTTP header
connection.setRequestProperty("access_token", test.getAuth());
connection.setDoOutput(true);
connection.getOutputStream().write(httpArg.getBytes("UTF-8"));
connection.connect();
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
sbf.append("rn");
}
reader.close();
result = sbf.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
注意:
ak和sk就是百度云创建应用对应的ak和sk
运行结果
小程序和后台源码关注下边公众号获取



