OcrApi.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: leo
  5. * Date: 2018/5/22
  6. * Time: 上午9:39
  7. */
  8. namespace common\helpers\ocr;
  9. use common\helpers\Cache;
  10. use common\helpers\ocr\baidu\AipOcr;
  11. use common\helpers\Tool;
  12. use yii\base\BaseObject;
  13. use yii\base\StaticInstanceTrait;
  14. class OcrApi extends BaseObject {
  15. use StaticInstanceTrait;
  16. const TYPE_BAIDU = 'baidu';
  17. const BAIDU_CONFIGS = [
  18. 'appId' => 'string',
  19. 'apiKey' => 'string',
  20. 'secretKey' => 'string',
  21. ];
  22. private $_type;
  23. private $_typeClass;
  24. private $_ocrApiObj;
  25. private $_errorCode;
  26. /**
  27. * 初始化
  28. * @throws \yii\base\InvalidConfigException
  29. */
  30. public function init() {
  31. parent::init();
  32. // 获取当前使用的ocr识别接口
  33. $ocrApiConfig = Cache::getOcrApiConfig();
  34. $this->_type = $ocrApiConfig['API_NAME'];
  35. $this->_typeClass = null;
  36. $apiConfig = [];
  37. if ($ocrApiConfig['API_NAME'] == self::TYPE_BAIDU) {
  38. $this->_typeClass = AipOcr::class;
  39. foreach ($ocrApiConfig['CONFIG'] as $value) {
  40. $apiConfig[] = $value;
  41. }
  42. }
  43. $this->_errorCode = require_once \Yii::getAlias('@common/helpers/ocr/baidu/') . 'errorCode.php';
  44. // 创建ocr识别接口对象
  45. $this->_ocrApiObj = \Yii::createObject($this->_typeClass, $apiConfig);
  46. }
  47. /**
  48. * 身份证识别
  49. * @param $image
  50. * @param array $params
  51. * [
  52. * 'idCardSide' => 'front' | 'back',
  53. * 'options' => [
  54. * 'detect_direction' => false,
  55. * 'detect_risk' => false,
  56. * ],
  57. * ]
  58. * @return null | array
  59. */
  60. public function idCard($image, array $params = []) {
  61. $result = null;
  62. $image = file_get_contents($image);
  63. if ($this->_type === self::TYPE_BAIDU) {
  64. $default = [
  65. 'idCardSide' => 'front',
  66. 'options' => [
  67. 'detect_direction' => false,
  68. 'detect_risk' => false,
  69. ],
  70. ];
  71. $argv = Tool::deepParse($params, $default);
  72. $tempResult = $this->_ocrApiObj->idcard($image, $argv['idCardSide'], $argv['options']);
  73. $errorCode = $this->_errorCode;
  74. if (isset($tempResult['error_code'])) {
  75. $result = [
  76. 'success' => false,
  77. 'message' => $errorCode[$tempResult['error_code']]['zh'] ?? '未知错误',
  78. ];
  79. } else {
  80. $message = '';
  81. switch ($tempResult['image_status']) {
  82. case 'normal':
  83. $message = '识别正常';
  84. break;
  85. case 'reversed_side':
  86. $message = '未摆正身份证';
  87. break;
  88. case 'non_idcard':
  89. $message = '上传的图片中不包含身份证';
  90. break;
  91. case 'blurred':
  92. $message = '身份证模糊';
  93. break;
  94. case 'over_exposure':
  95. $message = '身份证关键字段反光或过曝';
  96. break;
  97. case 'unknown':
  98. $message = '未知错误';
  99. break;
  100. default :
  101. $message = '未知错误';
  102. break;
  103. }
  104. $result = [
  105. 'success' => $tempResult['image_status'] == 'normal' ? true : false,
  106. 'message' => $message,
  107. 'address' => $tempResult['words_result']['住址']['words'] ?? null,
  108. 'idCardNo' => $tempResult['words_result']['公民身份号码']['words'] ?? null,
  109. 'birthDay' => $tempResult['words_result']['出生']['words'] ?? null,
  110. 'realName' => $tempResult['words_result']['姓名']['words'] ?? null,
  111. 'sex' => $tempResult['words_result']['性别']['words'] ?? null,
  112. 'nation' => $tempResult['words_result']['民族']['words'] ?? null,
  113. ];
  114. }
  115. }
  116. return $result;
  117. }
  118. /**
  119. * 增值税发票识别
  120. * @param $image
  121. * @param array $params
  122. * [
  123. * 'options' => [
  124. * 'accuracy' => normal,
  125. * ],
  126. * ]
  127. * @return array|null
  128. */
  129. public function vatInvoice($image, array $params = []) {
  130. $result = null;
  131. $image = file_get_contents($image);
  132. if ($this->_type === self::TYPE_BAIDU) {
  133. $default = [
  134. 'options' => [
  135. 'accuracy' => 'normal',
  136. ],
  137. ];
  138. $argv = Tool::deepParse($params, $default);
  139. $tempResult = $this->_ocrApiObj->vatInvoice($image, $argv['options']);
  140. $errorCode = $errorCode = $this->_errorCode;;
  141. if (isset($tempResult['error_code'])) {
  142. $result = [
  143. 'success' => false,
  144. 'message' => $errorCode[$tempResult['error_code']]['zh'] ?? '未知错误',
  145. ];
  146. } else {
  147. $result = [
  148. 'success' => true,
  149. 'message' => '识别正常',
  150. 'invoiceCode' => $tempResult['words_result']['InvoiceCode'] ?? null,
  151. 'invoiceNum' => $tempResult['words_result']['InvoiceNum'] ?? null,
  152. 'invoiceDate' => $tempResult['words_result']['InvoiceDate'] ?? null,
  153. 'amount' => $tempResult['words_result']['AmountInFiguers'] ?? null,
  154. 'taxRate' => $tempResult['words_result']['CommodityTaxRate'][0]['word'] ?? null,
  155. 'purchaserName' => $tempResult['words_result']['PurchaserName'] ?? null,
  156. 'purchaserRegisterNum' => $tempResult['words_result']['PurchaserRegisterNum'] ?? null,
  157. 'purchaserAddress' => $tempResult['words_result']['PurchaserAddress'] ?? null,
  158. 'purchaserBank' => $tempResult['words_result']['PurchaserBank'] ?? null,
  159. 'sellerName' => $tempResult['words_result']['SellerName'] ?? null,
  160. 'sellerRegisterNum' => $tempResult['words_result']['SellerRegisterNum'] ?? null,
  161. 'sellerAddress' => $tempResult['words_result']['SellerAddress'] ?? null,
  162. 'sellerBank' => $tempResult['words_result']['SellerBank'] ?? null,
  163. 'itemName' => $tempResult['words_result']['CommodityName'][0]['word'] ?? null,
  164. 'invoiceRemark' => $tempResult['words_result']['Remarks'] ?? null,
  165. ];
  166. //$result = array_merge($result, $tempResult);
  167. }
  168. }
  169. return $result;
  170. }
  171. /**
  172. * 获取api设置的字段
  173. * @param $apiName
  174. * @return array
  175. */
  176. public static function apiConfigs($apiName) {
  177. $allApiModelData = \common\models\OcrApi::getAllData();
  178. $result = [];
  179. if ($apiName == self::TYPE_BAIDU) {
  180. $result = [
  181. 'appId' => ['TITLE' => 'AppId', 'CONFIG_NAME' => 'appId', 'INPUT_TYPE' => 1, 'OPTIONS' => null, 'VALUE' => $allApiModelData[self::TYPE_BAIDU]['CONFIG']['appId'] ?? null],
  182. 'apiKey' => ['TITLE' => 'ApiKey', 'CONFIG_NAME' => 'apiKey', 'INPUT_TYPE' => 1, 'OPTIONS' => null, 'VALUE' => $allApiModelData[self::TYPE_BAIDU]['CONFIG']['apiKey'] ?? null],
  183. 'secretKey' => ['TITLE' => 'SecretKey', 'CONFIG_NAME' => 'secretKey', 'INPUT_TYPE' => 1, 'OPTIONS' => null, 'VALUE' => $allApiModelData[self::TYPE_BAIDU]['CONFIG']['secretKey'] ?? null],
  184. ];
  185. }
  186. return $result;
  187. }
  188. }