| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- <?php
- /**
- * 重庆赤晓店信息科技有限公司
- * https://www.chixiaodian.com
- * Copyright (c) 2023 赤店商城 All rights reserved.
- */
- namespace app\utils\Ocr;
- use app\models\Option;
- use app\utils\Ocr\Constant\ContentType;
- use app\utils\Ocr\Constant\HttpHeader;
- use app\utils\Ocr\Constant\HttpMethod;
- use app\utils\Ocr\Constant\SystemHeader;
- use app\utils\Ocr\Http\HttpClient;
- use app\utils\Ocr\Http\HttpRequest;
- use yii\db\Exception;
- use app\utils\CurlHelper;
- use yii\helpers\Json;
- class OcrApi
- {
- /**
- * 营业执照
- */
- const TYPE_LICENSE = 1;
- /**
- * 身份证信息
- */
- const TYPE_ID_CARD = 2;
- /**
- * 银行卡信息
- */
- const TYPE_BANK = 3;
- /**
- * 通用文字信息
- */
- const TYPE_TEXT = 4;
- /**
- * 校验数组
- * @var int[]
- */
- public static $validType = [
- self::TYPE_LICENSE,
- self::TYPE_ID_CARD,
- self::TYPE_BANK,
- self::TYPE_TEXT
- ];
- /**
- * 身份证正面
- */
- const SIDE_FACE = 'face';
- /**
- * 身份证反面
- */
- const SIDE_BACK = 'back';
- /**
- * 调用app_key
- * @var string
- */
- private $app_key;
- /**
- * 调用app_secret
- * @var string
- */
- private $app_secret;
- /**
- * 营业执照
- * @var string
- */
- private $business_license_api = 'https://bizlicense.market.alicloudapi.com/rest/160601/ocr/ocr_business_license.json';
- /**
- * 身份证
- * @var string
- */
- private $id_card_api = 'https://cardnumber.market.alicloudapi.com/rest/160601/ocr/ocr_idcard.json';
- //https://market.aliyun.com/apimarket/detail/cmapi010401#sku=yuncode4401000018开通地址
- /**
- * 通用文字识别
- */
- private $text_recognition = "https://tysbgpu.market.alicloudapi.com/api/predict/ocr_general";
- //https://market.aliyun.com/apimarket/detail/cmapi020020#sku=yuncode1402000000开通地址
- /**
- * 银行卡
- * @var string
- */
- private $bank_card_api = 'https://yhk.market.alicloudapi.com/rest/160601/ocr/ocr_bank_card.json';
- //https://market.aliyun.com/apimarket/detail/cmapi016870#sku=yuncode10870000013开通地址
- public function __construct($is_platform = false) {
- if ($is_platform) {
- $saas_ocr = Option::get('ocr', 0, 'saas', '{"app_key": "", "app_secret": ""}')['value'];
- $ocr_setting_info = Json::decode($saas_ocr);
- $app_key = $ocr_setting_info['app_key'];
- $app_secret = $ocr_setting_info['app_secret'];
- } else {
- $store_ocr = Option::get('ocr', get_store_id(), 'store', '{"app_key": "", "app_secret": ""}')['value'];
- $ocr_setting_info = Json::decode($store_ocr);
- if(empty($ocr_setting_info['app_key']) || empty($ocr_setting_info['app_secret'])){
- $saas_ocr = Option::get('ocr', 0, 'saas', '{"app_key": "", "app_secret": ""}')['value'];
- $ocr_setting_info = Json::decode($saas_ocr);
- }
- $app_key = $ocr_setting_info['app_key'];
- $app_secret = $ocr_setting_info['app_secret'];
- }
- if (empty($app_key) || empty($app_secret)) {
- throw new \Exception('获取配置信息失败');
- }
- $this->app_key = $app_key;
- $this->app_secret = $app_secret;
- }
- /**
- * @param $url
- * @param $appKey
- * @param $appSecret
- * @param $bodyContent
- * @return Http\HttpResponse
- */
- private function doPost($url, $appKey, $appSecret, $bodyContent)
- {
- // 域名后、query前的部分
- $urlEles = parse_url($url);
- $host = $urlEles["scheme"] . "://" . $urlEles["host"];
- $path = $urlEles["path"];
- $request = new HttpRequest($host, $path, HttpMethod::POST, $appKey, $appSecret);
- // 设定Content-Type,根据服务器端接受的值来设置
- $request->setHeader(HttpHeader::HTTP_HEADER_CONTENT_TYPE, ContentType::CONTENT_TYPE_JSON);
- // 设定Accept,根据服务器端接受的值来设置
- $request->setHeader(HttpHeader::HTTP_HEADER_ACCEPT, ContentType::CONTENT_TYPE_JSON);
- // 注意:业务body部分,不能设置key值,只能有value
- if (0 < strlen($bodyContent)) {
- $request->setHeader(HttpHeader::HTTP_HEADER_CONTENT_MD5, base64_encode(md5($bodyContent, true)));
- $request->setBodyString($bodyContent);
- }
- // 指定参与签名的header
- $request->setSignHeader(SystemHeader::X_CA_TIMESTAMP);
- $response = HttpClient::execute($request);
- return $response;
- }
- /**
- * 营业执照识别
- * @param $image_url
- */
- public function getBusinessLicense($image_url, $type = 0)
- {
- $cache_key = 'ocr_license_' . md5($image_url);
- if ($license = cache()->get($cache_key)) {
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $this->handleLicenseData($license)
- ];
- }
- $url = $this->business_license_api;
- $file = $image_url;
- // 如果没有configure字段,configure设为空
- $configure = [];
- if (substr($file, 0, 4) == "http") {
- if ($type) {
- $file = $this->imgToBase64($file);
- }
- $base64 = $file;
- } else if ($fp = fopen($file, "rb", 0)) {
- $binary = fread($fp, filesize($file)); // 文件读取
- fclose($fp);
- $base64 = base64_encode($binary); // 转码
- }
- $request = [
- 'image' => "$base64"
- ];
- if (count($configure) > 0) {
- $request["configure"] = json_encode($configure);
- }
- $body = json_encode($request);
- $response = $this->doPost($url, $this->app_key, $this->app_secret, $body);
- $stat = $response->getHttpStatusCode();
- if ($stat == 200) {
- $result_str = $response->getBody();
- $data = Json::decode($result_str);
- cache()->set($cache_key, $data, 30 * 60);
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $this->handleLicenseData($data)
- ];
- } elseif ($stat == 462) {
- return $this->getBusinessLicense($image_url, 1);
- } else {
- return [
- 'code' => $stat,
- 'msg' => 'fail'
- ];
- // printf("Http error code: %d\n", $stat);
- // printf("Error msg in body: %s\n", $response->getBody());
- // printf("header: %s\n", $response->getHeader());
- }
- }
- /**
- * 身份证识别
- * @param string $image_url
- * @param string $side
- */
- public function getIDCard($image_url, $side = self::SIDE_FACE, $type = 0)
- {
- $cache_key = 'ocr_id_card_' . md5($image_url) . '_' . $side;
- if ($card = cache()->get($cache_key)) {
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $this->handleIDCardData($card, $side)
- ];
- }
- $url = $this->id_card_api;
- $file = $image_url;
- // 如果没有configure字段,configure设为空
- $configure = [
- 'side' => $side
- ];
- if (substr($file, 0, 4) == "http") {
- if ($type) {
- $file = $this->imgToBase64($file);
- }
- $base64 = $file;
- } else if ($fp = fopen($file, "rb", 0)) {
- $binary = fread($fp, filesize($file)); // 文件读取
- fclose($fp);
- $base64 = base64_encode($binary); // 转码
- }
- $request = [
- 'image' => "$base64"
- ];
- if (count($configure) > 0) {
- $request["configure"] = json_encode($configure);
- }
- $body = json_encode($request);
- $response = $this->doPost($url, $this->app_key, $this->app_secret, $body);
- $stat = $response->getHttpStatusCode();
- if ($stat == 200) {
- $result_str = $response->getBody();
- $data = Json::decode($result_str);
- cache()->set($cache_key, $data, 30 * 60);
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $this->handleIDCardData($data, $side)
- ];
- } elseif ($stat == 462) {
- return $this->getIDCard($image_url, $side, 1);
- } else {
- return [
- 'code' => $stat,
- 'msg' => 'fail'
- ];
- // printf("Http error code: %d\n", $stat);
- // printf("Error msg in body: %s\n", $response->getBody());
- // printf("header: %s\n", $response->getHeader());
- }
- }
- /**
- * 银行卡
- * @param string $image_url
- * @param string $side
- */
- public function getBankCard($image_url, $type = 0)
- {
- $cache_key = 'ocr_bank_card_' . md5($image_url);
- if ($bank = cache()->get($cache_key)) {
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $this->handleBankCardData($bank)
- ];
- }
- $url = $this->bank_card_api;
- $file = $image_url;
- // 如果没有configure字段,configure设为空
- $configure = [
- 'card_type' => true
- ];
- if (substr($file, 0, 4) == "http") {
- if ($type) {
- $file = $this->imgToBase64($file);
- }
- $base64 = $file;
- } else if ($fp = fopen($file, "rb", 0)) {
- $binary = fread($fp, filesize($file)); // 文件读取
- fclose($fp);
- $base64 = base64_encode($binary); // 转码
- }
- $request = [
- 'image' => "$base64"
- ];
- if (count($configure) > 0) {
- $request["configure"] = json_encode($configure);
- }
- $body = json_encode($request);
- $response = $this->doPost($url, $this->app_key, $this->app_secret, $body);
- $stat = $response->getHttpStatusCode();
- if ($stat == 200) {
- $result_str = $response->getBody();
- $data = Json::decode($result_str);
- cache()->set($cache_key, $data, 30 * 60);
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $this->handleBankCardData($data)
- ];
- } elseif ($stat == 462) {
- return $this->getBankCard($image_url, 1);
- } else {
- return [
- 'code' => $stat,
- 'msg' => 'fail'
- ];
- // printf("Http error code: %d\n", $stat);
- // printf("Error msg in body: %s\n", $response->getBody());
- // printf("header: %s\n", $response->getHeader());
- }
- }
- /**
- * 处理文字识别数据
- */
- public function getTextRecognition($image_url, $type = 0) {
- $url = $this->text_recognition;
- $file = $image_url;
- $configure = [
- 'output_prob' => false,
- 'output_keypoints' => false,
- 'skip_detection' => false,
- 'dir_assure' => false,
- 'language' => 'sx'
- ];
- if (substr($file, 0, 4) == "http") {
- if ($type) {
- $file = $this->imgToBase64($file);
- }
- $base64 = $file;
- } else if ($fp = fopen($file, "rb", 0)) {
- $binary = fread($fp, filesize($file)); // 文件读取
- fclose($fp);
- $base64 = base64_encode($binary); // 转码
- }
- $request = [
- 'image' => "$base64"
- ];
- if (count($configure) > 0) {
- $request["configure"] = $configure;
- }
- $body = json_encode($request);
- $response = $this->doPost($url, $this->app_key, $this->app_secret, $body);
- $stat = $response->getHttpStatusCode();
- $result_str = $response->getBody();
- $str = "";
- if ($stat == 200) {
- $result = json_decode($result_str, true);
- if (!empty($result['ret'])) {
- foreach ($result['ret'] as $ret) {
- $str .= $ret['word'] . " ";
- }
- }
- return [
- 'code' => 0,
- 'msg' => '识别成功',
- 'data' => [
- 'result' => $result,
- 'str' => $str
- ]
- ];
- }
- return [
- 'code' => 1,
- 'msg' => '识别失败',
- 'data' => $result_str
- ];
- }
- /**
- * 处理拿到的营业执照数据
- */
- private function handleLicenseData($res) {
- if (empty($res)) {
- return [];
- }
- $data = [
- 'address' => $res['address'],
- 'business' => $res['business'],
- 'capital' => $res['capital'],
- 'establish_date' => $this->handleDate($res['establish_date']),
- 'name' => $res['name'],
- 'person' => $res['person'],
- 'reg_num' => $res['reg_num'],
- 'type' => $res['type'],
- 'valid_period' => $this->handleDate($res['valid_period'])
- ];
- return $data;
- }
- /**
- * 处理拿到的身份证信息数据
- */
- private function handleIDCardData($res, $side = self::SIDE_FACE) {
- if (empty($res)) {
- return [];
- }
- if ($side == self::SIDE_FACE) {
- $data = [
- 'address' => $res['address'],
- 'birth' => $this->handleDate($res['birth']),
- 'name' => $res['name'],
- 'nationality' => $res['nationality'],
- 'num' => $res['num'],
- 'sex' => $res['sex']
- ];
- } else {
- $data = [
- 'end_date' => $this->handleDate($res['end_date']),
- 'issue' => $res['issue'],
- 'start_date' => $this->handleDate($res['start_date'])
- ];
- }
- return $data;
- }
- /**
- * 处理拿到的银行卡信息数据
- */
- private function handleBankCardData($res) {
- if (empty($res)) {
- return [];
- }
- $data = [
- 'bank_name' => $res['bank_name'],
- 'card_num' => $res['card_num'],
- 'card_type' => $res['card_type'],
- 'valid_date' => $res['valid_date']
- ];
- return $data;
- }
- /**
- * 处理日期20220101 to 2020-01-01
- * @param $date
- */
- private function handleDate($date) {
- if (is_numeric($date)){
- return substr($date, 0 , 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2);
- } else {
- return $date;
- }
- }
- public function imgToBase64($img_file) {
- $img_file = $this->saveTempImage($img_file);
- $img_base64 = '';
- if (file_exists($img_file)) {
- $app_img_file = $img_file; // 图片路径
- $img_info = getimagesize($app_img_file); // 取得图片的大小,类型等
- //echo '<pre>' . print_r($img_info, true) . '</pre><br>';
- $fp = fopen($app_img_file, "r"); // 图片是否可读权限
- if ($fp) {
- $filesize = filesize($app_img_file);
- $content = fread($fp, $filesize);
- $file_content = chunk_split(base64_encode($content)); // base64编码
- switch ($img_info[2]) { //判读图片类型
- case 1: $img_type = "gif";
- break;
- case 2: $img_type = "jpg";
- break;
- case 3: $img_type = "png";
- break;
- }
- $img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码
- }
- fclose($fp);
- }
- return $img_base64; //返回图片的base64
- }
- //获取网络图片到临时目录
- public function saveTempImage($url)
- {
- if (strpos($url,'http') === false) {
- $url = 'http:'. trim($url);
- }
- if (!is_dir(\Yii::$app->runtimePath . '/image')) {
- mkdir(\Yii::$app->runtimePath . '/image');
- }
- $save_path = \Yii::$app->runtimePath . '/image/' . md5($url) . '.jpg';
- CurlHelper::download($url, $save_path);
- return $save_path;
- }
- }
|