百度卡证文字识别
公司有个业务需求,是调用百度的卡证文字识别api,然后自动填入对应字段
看完文档封装了一个服务类,希望对大家有帮助
图片支持base64和url的形式,原本打算直接用url的形式,但是我测试之后发现有个问题,百度那边对于url,会时不时出现下载超时或者下载失败的情况
就想了个方案,先把图片url转base64,再用base64的方式去调用接口
1.下面是示例代码,首先是对应得方法
/**
* 卡证文字识别
*
* @author panzhide
* @time 2025-02-26 14:21:41
* @return void
*/
public function certificate_image_identify()
{
$url = I('url', '');
$type = I('type', ''); // 图片类型:1=身份证,2=银行卡,3=营业执照
if (!$url) {
$this->errmsg('参数有误');
}
if (!$type) {
$this->errmsg('图片类型参数有误');
}
// 图片装base64编码,避免图片url失效
$baseimg = url2base64($url);
$image = preg_replace('/^data:image\/[^;]+;base64,/', '', $baseimg);
import('Org.BaiduOcrClient', COMMON_PATH);
$BaiduOcrClient = new \BaiduOcrClient();
try {
// 图片类型:1=身份证,2=银行卡,3=营业执照
switch ($type) {
case 1:
$return_data = $BaiduOcrClient->identifyIdCard($url, $image);
break;
case 2:
$return_data = $BaiduOcrClient->recognizeBankCard($url, $image);
break;
case 3:
$return_data = $BaiduOcrClient->recognizeBusinessLicense($url, $image);
break;
default:
$return_data = $BaiduOcrClient->recognizeBusinessLicense($url, $image);
break;
}
$data['data'] = $return_data;
$this->out($data);
} catch (\Exception $e) {
$this->errmsg($e->getMessage());
}
}
2.图片url转base64的方法
/**
* 图片url转base64
*/
if(! function_exists('url2base64')) {
function url2base64($url)
{
$img_type = pathinfo($url)['extension'];
if(empty($img_type)){
return '';
}
$file_content = (base64_encode(file_get_contents($url)));
if(empty($file_content)){
return '';
}
return 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码
}
}
3.百度对应的服务类
<?php
class BaiduOcrClient
{
const ACCESS_TOKEN_CACHE_KEY = 'baidu_ocr_access_token';
const ACCESS_TOKEN_EXPIRY = 3600; // 1小时有效期
private $apiKey;
private $secretKey;
public function __construct() // 去掉类型提示
{
$cfg = load_site_config();
$this->apiKey = $cfg['baidu_api']["client_id"];
$this->secretKey = $cfg['baidu_api']["client_secret"];
}
/**
* 身份证识别
*
* @param string $imageContent 图片二进制内容或URL
* @param array $options 可选参数
* @return array
*/
public function identifyIdCard($url, $image, $options = []) // 去掉类型提示
{
$baseParams = [
'id_card_side' => 'front',
'detect_ps' => 'false',
'detect_risk' => 'false',
'detect_quality' => 'false',
'detect_photo' => 'false',
'detect_card' => 'false',
'detect_direction' => 'false',
'url' => $url,
'image' => $image
];
return $this->request(
'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard',
array_merge($baseParams, $options, ['url' => $url, 'image' => $image,])
);
}
/**
* 银行卡识别
*
* @param string $imageContent 图片二进制内容或URL
* @param array $options 可选参数
* @return array
*/
public function recognizeBankCard($url, $image, $options = []) // 去掉类型提示
{
$baseParams = [
'url' => $url,
'image' => $image,
'detect_quality' => 'false'
];
return $this->request(
'https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard',
array_merge($baseParams, $options)
);
}
/**
* 营业执照识别
*
* @param string $imageContent 图片二进制内容或URL
* @param array $options 可选参数
* @return array
*/
public function recognizeBusinessLicense($url, $image, $options = []) // 去掉类型提示
{
$baseParams = [
'url' => $url,
'image' => $image,
'detect_quality' => 'false'
];
return $this->request(
'https://aip.baidubce.com/rest/2.0/ocr/v1/business_license',
array_merge($baseParams, $options)
);
}
/**
* 执行API请求
*/
private function request($url, $params) // 去掉类型提示
{
$ch = curl_init();
try {
$query = http_build_query(['access_token' => $this->getAccessToken()]);
curl_setopt_array($ch, [
CURLOPT_URL => "{$url}?{$query}",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_POSTFIELDS => $this->buildPostData($params),
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json'
],
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($error = curl_error($ch)) {
throw new RuntimeException("CURL Error: {$error}");
}
return $this->parseResponse($response);
} finally {
curl_close($ch);
}
}
/**
* 处理API响应
*/
private function parseResponse($response) // 去掉类型提示
{
$data = json_decode($response, true);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new RuntimeException('JSON Parse Error: ' . json_last_error_msg());
}
if (!empty($data['error_code'])) {
throw new RuntimeException("API Error [{$data['error_code']}]: {$data['error_msg']}");
}
return $data;
}
/**
* 构建POST数据(支持文件内容)
*/
private function buildPostData($params) // 去掉类型提示
{
// image和url同时存在,则保留url
if (empty($params['image'])) {
unset($params['image']);
}
if (empty($params['url'])) {
unset($params['url']);
}
if ($params['image'] && $params['url']) {
unset($params['url']);
}
return http_build_query($params);
}
private function getAccessToken()
{
// 从缓存获取Access Token
$cached = SS(self::ACCESS_TOKEN_CACHE_KEY);
if ($cached && $this->isTokenValid($cached)) {
return $cached['token'];
}
// 请求新的Access Token
$ch = curl_init();
try {
curl_setopt_array($ch, [
CURLOPT_URL => 'https://aip.baidubce.com/oauth/2.0/token',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'client_credentials',
'client_id' => $this->apiKey,
'client_secret' => $this->secretKey,
]),
]);
$response = curl_exec($ch);
if ($error = curl_error($ch)) {
throw new RuntimeException("Token Request Failed: {$error}");
}
$data = json_decode($response, true);
if (!isset($data['access_token'])) {
throw new RuntimeException('Failed to get access token');
}
// 使用SS()缓存带有效期信息
$cacheData = [
'token' => $data['access_token'],
'expiry' => time() + (int)($data['expires_in'] ?: self::ACCESS_TOKEN_EXPIRY)
];
SS(self::ACCESS_TOKEN_CACHE_KEY, $cacheData, $cacheData['expiry'] - time());
return $cacheData['token'];
} finally {
curl_close($ch);
}
}
private function isTokenValid($cached) // 去掉类型提示
{
return isset($cached['expiry']) && $cached['expiry'] > time();
}
private function isUrl($str) // 去掉类型提示
{
return filter_var($str, FILTER_VALIDATE_URL) !== false;
}
}
4.服务类中有用的缓存,建议替换成redis,我这边是系统太老没得办法
/**
* 缓存管理
* @param mixed $name 缓存名称,如果为数组表示进行缓存设置
* @param mixed $value 缓存值
* @param mixed $options 缓存参数
* @return mixed
*/
function SS($name, $value = '', $options = null)
{
static $cache = '';
if (is_array($options) && empty($cache)) {
// 缓存操作的同时初始化
$type = isset($options['type']) ? $options['type'] : '';
$cache = Think\Cache::getInstance($type, $options);
} elseif (is_array($name)) { // 缓存初始化
$type = isset($name['type']) ? $name['type'] : '';
$cache = Think\Cache::getInstance($type, $name);
return $cache;
} elseif (empty($cache)) { // 自动初始化
$type = C('DATA_CACHE_TYPE');
$options = C('DATA_CACHE_OPTIONS');
$cache = Think\Cache::getInstance($type, $options);
}
if ('' === $value) { // 获取缓存
return $cache->get($name);
} elseif (is_null($value)) { // 删除缓存
return $cache->rm($name);
} else { // 缓存数据
if (is_array($options)) {
$expire = isset($options['expire']) ? $options['expire'] : NULL;
} else {
$expire = is_numeric($options) ? $options : NULL;
}
return $cache->set($name, $value, $expire);
}
}

浙公网安备 33010602011771号