印刷文字识别-身份证识别(阿里云)
以下是自己根据阿里云api文档说明封装的工具类,主要是获取阿里云Oss身份证图片信息
阿里云api文档URL:https://market.aliyun.com/products/57124001/cmapi010401.html?spm=a2c4g.11186623.2.7.VojbRu
<?php namespace Helper; use org\Response; use think\Controller; use think\Request; use think\Db; use think\Loader; /** * 身份证识别 * Class AutoRecognition * @package Helper * @author fgf <2018-06-07> */ class AutoRecognition { /** * 读取远程图片的二进制流 * @param string $url 远程图片URL地址 * @return bool|string */ public static function httpDownload($url=''){ if(empty($url)){ return false; } ob_start(); $contents = @readfile($url); $img = ob_get_contents(); ob_end_clean(); return $img; } /** * 身份证正面识别 * $file 你的文件路径 * $param $appcode 阿里云APPCODE * @return array */ public static function face($file='') { if (empty($file)) { return Response::response(1,'图片为空'); } //请求阿里云api地址 $url = "https://dm-51.data.aliyun.com/rest/160601/ocr/ocr_idcard.json"; $appcode = config('APPCODE');//读取配置文件阿里云APPCODE //你的文件路径 //$file = "你的文件路径"; //如果输入带有inputs, 设置为True,否则设为False $is_old_format = false; //如果没有configure字段,config设为空 $config = array( "side" => "face"//身份证正反面类型:face/back ); //$config = array() //打开文件 if($fp = @fopen($file, "rb", 0)) { //$binary = fread($fp, filesize($file)); // 文件读取-filesize无法获取远程文件的大小,只能读取path路径文件 $binary = self::httpDownload($file); // 文件读取-读取远程图片的二进制流 fclose($fp); $base64 = base64_encode($binary); // 转码 }else{ return Response::response(1,'图片打开失败,请检查图片路径是否正确'); } $headers = array(); array_push($headers, "Authorization:APPCODE " . $appcode); //根据API的要求,定义相对应的Content-Type array_push($headers, "Content-Type".":"."application/json; charset=UTF-8"); $querys = ""; if($is_old_format == TRUE){ $request = array(); $request["image"] = array( "dataType" => 50, "dataValue" => "$base64" ); if(count($config) > 0){ $request["configure"] = array( "dataType" => 50, "dataValue" => json_encode($config) ); } $body = json_encode(array("inputs" => array($request))); }else{ $request = array( "image" => "$base64" ); if(count($config) > 0){ $request["configure"] = json_encode($config); } $body = json_encode($request); } $method = "POST"; $curl = curl_init(); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_FAILONERROR, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); if (1 == strpos("$".$url, "https://")) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); } curl_setopt($curl, CURLOPT_POSTFIELDS, $body); $result = curl_exec($curl); $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $rheader = substr($result, 0, $header_size); $rbody = substr($result, $header_size); $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE); if($httpCode == 200){ if($is_old_format){ $output = json_decode($rbody, true); $result_str = $output["outputs"][0]["outputValue"]["dataValue"]; }else{ $result_str = $rbody; } //printf("result is :\n %s\n", $result_str);//这是阿里原生的结果打印 //身份证读取内容输出 return Response::response(0, json_decode($result_str)); }else{ //printf("Http error code: %d\n", $httpCode);//这是阿里原生的结果打印 //printf("Error msg in body: %s\n", $rbody);//这是阿里原生的结果打印 //printf("header: %s\n", $rheader);//这是阿里原生的结果打印 return Response::response(1,'获取身份信息失败'); } } /** * 身份证反面识别 * $param $file 你的文件路径 * $param $appcode 阿里云APPCODE * @param string $file */ public static function back($file='') { if (empty($file)) { return Response::response(1,'图片为空'); } //请求阿里云api地址 $url = "https://dm-51.data.aliyun.com/rest/160601/ocr/ocr_idcard.json"; $appcode = config('APPCODE');//读取配置文件阿里云APPCODE //你的文件路径 //$file = "你的文件路径"; //如果输入带有inputs, 设置为True,否则设为False $is_old_format = false; //如果没有configure字段,config设为空 $config = array( "side" => "back"//身份证正反面类型:face/back ); //$config = array() //打开文件 if($fp = @fopen($file, "rb", 0)) { //$binary = fread($fp, filesize($file)); // 文件读取-filesize无法获取远程文件的大小,只能读取path路径文件 $binary = self::httpDownload($file); // 文件读取-读取远程图片的二进制流 fclose($fp); $base64 = base64_encode($binary); // 转码 }else{ return Response::response(1,'图片打开失败,请检查图片路径是否正确'); } $headers = array(); array_push($headers, "Authorization:APPCODE " . $appcode); //根据API的要求,定义相对应的Content-Type array_push($headers, "Content-Type".":"."application/json; charset=UTF-8"); $querys = ""; if($is_old_format == TRUE){ $request = array(); $request["image"] = array( "dataType" => 50, "dataValue" => "$base64" ); if(count($config) > 0){ $request["configure"] = array( "dataType" => 50, "dataValue" => json_encode($config) ); } $body = json_encode(array("inputs" => array($request))); }else{ $request = array( "image" => "$base64" ); if(count($config) > 0){ $request["configure"] = json_encode($config); } $body = json_encode($request); } $method = "POST"; $curl = curl_init(); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_FAILONERROR, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); if (1 == strpos("$".$url, "https://")) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); } curl_setopt($curl, CURLOPT_POSTFIELDS, $body); $result = curl_exec($curl); $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $rheader = substr($result, 0, $header_size); $rbody = substr($result, $header_size); $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE); if($httpCode == 200){ if($is_old_format){ $output = json_decode($rbody, true); $result_str = $output["outputs"][0]["outputValue"]["dataValue"]; }else{ $result_str = $rbody; } //printf("result is :\n %s\n", $result_str);//这是阿里原生的结果打印 //身份证读取内容输出 return Response::response(0, json_decode($result_str)); }else{ //printf("Http error code: %d\n", $httpCode); //printf("Error msg in body: %s\n", $rbody); //printf("header: %s\n", $rheader); return Response::response(1,'获取身份信息失败'); } } }
工具类在tp5.0中的结构位置如下图
正常返回示例
正面返回结果: { "address" : "浙江省杭州市余杭区文一西路969号", #地址信息 "config_str" : "{\\\"side\\\":\\\"face\\\"}", #配置信息,同输入configure "face_rect":{ "angle": -90, "center":{ "x" : 952, "y" : 325.5 }, "size":{ "height":181.99, "width":164.99 } }, #人脸位置,center表示人脸矩形中心坐标,size表示人脸矩形长宽,angle表示矩形顺时针旋转的度数。 "name" : "张三", #姓名 "nationality": "汉", #民族 "num" : "1234567890", #身份证号 "sex" : "男", #性别 "birth" : "20000101", #出生日期 "nationality" : "汉", #民族 "success" : true #识别结果,true表示成功,false表示失败 } 反面返回结果: { "config_str" : "{\\\"side\\\":\\\"back\\\"}",#配置信息,同输入configure "start_date" : "19700101", #有效期起始时间 "end_date" : "19800101", #有效期结束时间 "issue" : "杭州市公安局", #签发机关 "success" : true #识别结果,true表示成功,false表示失败 }
使用此工具类可参考如下步骤
1.Controller引入工具类 use Helper\AutoRecognition;
2.方法接收参数 idcard_b-身份证正面 idcard_a-身份证国徽面
public function save(Request $request) { $param = $request->only(['username', 'idnum', 'mobile', 'idcard_a', 'idcard_b']); $param['userid'] = $this->userid; $param['status'] = 0; //身份证正面识别 $res = self::check_idcard_face_message($param); if (!$res) { return Response::response(1,'填写身份证号码与证件号码不符'); } //身份证反面识别 $res1 = self::check_idcard_back_message($param); if (!$res1) { return Response::response(1,'身份证已过期'); } }
3.调用工具类验证
/** * 身份证正面信息校对 * @param $file 身份证正面图片 * @return bool */ public static function check_idcard_face_message($param) { if ($param['idcard_b']) { $file = get_image_url($param['idcard_b']); } else { return false; } //调取阿里身份认证api获取身份证信息 $data = AutoRecognition::face($file); //dump($data);exit; if($data['data'] != '获取身份信息失败' && $data['data']->num == $param['idnum']){ return true; }else{ return false; } } /** * 身份证反面信息校对 * @param $file 身份证反面图片-国徽面 * @return bool */ public static function check_idcard_back_message($param) { if ($param['idcard_a']) { $file = get_image_url($param['idcard_a']); } else { return false; } //调取阿里身份认证api获取身份证信息 $data = AutoRecognition::back($file); //dump($data);exit; if ($data['data'] != '获取身份信息失败') { $end_date = $data['data']->end_date;//提取身份证过期时间 $y = substr($end_date,0,4);//截取年 $m = substr($end_date,4,2);//截取月 $d = substr($end_date,6,2);//截取日 $last_date_unix = strtotime($y.'-'.$m.'-'.$d);//身份证截止日时间戳 $today_unid = strtotime(date('Y-m-d'));//今日时间戳 //身份证截止日时间戳 > 今日时间戳,身份证未过期,返回true if($last_date_unix > $today_unid){ return true; } else { return false; } } else { return false; } }