当前位置:网站首页>Custom implementation of Baidu image recognition (instead of aipocr)
Custom implementation of Baidu image recognition (instead of aipocr)
2022-04-23 16:31:00 【Spilled off】
package com.visy.service;
import com.baidu.aip.util.Base64Util;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.visy.exception.ErrorEnum;
import com.visy.exception.BusinessException;
import com.visy.config.BaiduConfig;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Baidu image recognition custom implementation ( replace AipOcr)
* @author visy.wang
* @date 2022/1/19 9:24
*/
@Slf4j
@Service
public class AipOcrClient {
private static long expireTime = 0L; //token Expiration time stamp
private static String accessToken = null; //token value
@Autowired
private BaiduConfig baiduConfig; // Baidu authentication information , Configure your own apiKey and secretKey
@Autowired
private RestTemplate restTemplate;
//Url Management enumeration
@Getter
@AllArgsConstructor
enum UrlKey {
ACCESS_TOKEN("https://aip.baidubce.com/oauth/2.0/token", " Certification address "),
DRIVING_LICENSE("https://aip.baidubce.com/rest/2.0/ocr/v1/driving_license", " Driver's license identification address "),
VEHICLE_LICENSE("https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license", " Driving license identification address ");
private final String url;
private final String desc;
}
/**
* Driver's license identification
* @param image picture ( Binary system )
* @param options The other parameters
* @return Recognition result
*/
public JSONObject drivingLicense(byte[] image, HashMap<String,String> options){
options.put("image", Base64Util.encode(image));
return request(UrlKey.DRIVING_LICENSE, options);
}
/**
* Driver's license identification
* @param imageUrl Picture address
* @param options The other parameters
* @return Recognition result
*/
public JSONObject drivingLicense(String imageUrl, HashMap<String,String> options){
options.put("url", imageUrl);
return request(UrlKey.DRIVING_LICENSE, options);
}
/**
* Identification of driving license
* @param image picture ( Binary system )
* @param options The other parameters
* @return Recognition result
*/
public JSONObject vehicleLicense(byte[] image, HashMap<String,String> options){
options.put("image", Base64Util.encode(image));
return request(UrlKey.VEHICLE_LICENSE, options);
}
/**
* Identification of driving license
* @param imageUrl Picture address
* @param options The other parameters
* @return Recognition result
*/
public JSONObject vehicleLicense(String imageUrl, HashMap<String,String> options){
options.put("url", imageUrl);
return request(UrlKey.VEHICLE_LICENSE, options);
}
// belt Token Overdue inspection request, Temporarily unnecessary , The expiration time has been calculated and retrieved before expiration
private JSONObject requestWithTokenCheck(UrlKey urlKey, Map<String,String> options){
JSONObject res = request(urlKey, options);
if(res.has("error_code")){
int errCode = res.getInt("error_code");
if(errCode==110 || errCode==111){
accessToken = null; //Token invalid , Clear and retrieve
return request(urlKey, options);
}
}
return res;
}
/**
* request
* @param urlKey url Address enumeration
* @param options The other parameters
* @return Recognition result
*/
private JSONObject request(UrlKey urlKey, Map<String,String> options){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
String url = urlKey.getUrl();
MultiValueMap<String, String> queryStr = getQueryStr(urlKey);
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url).queryParams(queryStr);
MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
if(Objects.nonNull(options) && !options.isEmpty()){
options.forEach(formData::add);
}
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(formData, headers);
ResponseEntity<String> res = restTemplate.postForEntity(uriBuilder.toUriString(), request, String.class);
if(!HttpStatus.OK.equals(res.getStatusCode())){
throw buzError(" request was aborted :httpStatus=" + res.getStatusCode());
}
String resBody = res.getBody();
if(StringUtils.isBlank(resBody)){
throw buzError(" The response body is empty ");
}
return new JSONObject(resBody);
}
private MultiValueMap<String, String> getQueryStr(UrlKey urlKey){
MultiValueMap<String, String> queryStr = new LinkedMultiValueMap<>();
if(UrlKey.ACCESS_TOKEN.equals(urlKey)){
queryStr.add("grant_type", "client_credentials");
queryStr.add("client_id", baiduConfig.getApiKey());
queryStr.add("client_secret", baiduConfig.getSecretKey());
}else{
queryStr.add("access_token", getAccessToken()); // Add authentication information
}
return queryStr;
}
/**
* obtain AccessToken
* @return AccessToken
*/
private String getAccessToken(){
long now = System.currentTimeMillis();
if(StringUtils.isNotBlank(accessToken) && now<expireTime){
// There is a cache and it is within the validity period , Use it directly
return accessToken;
}
try{
return getAccessToken(now);
}catch (Exception e){
throw buzError("AccessToken Acquisition failure :" + e.getMessage());
}
}
private String getAccessToken(long now){
log.info(" Retrieving AccessToken...");
JSONObject body = request(UrlKey.ACCESS_TOKEN, null);
if(body.has("error")){
throw buzError(body.getString("error_description"));
}
int tokenExpires = body.getInt("expires_in"); // The period of validity , Unit second , Default 30 God
expireTime = now + (tokenExpires-86400L)*1000L; // advance 1 Days out
accessToken = body.getString("access_token"); // cache token
log.info(" Authentication success , Valid until :{}", new Date(expireTime));
return accessToken;
}
/**
* Throw business exception
* @param errMsg error message
* @return Business exceptions
*/
private BusinessException buzError(String errMsg){
//BusinessException: Custom business exception
return new BusinessException(ErrorEnum.BUSINESS_ERR.getCode(), errMsg);
}
}
package com.visy.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author visy.wang
* @date 2022/1/19 9:28
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "baidu")
public class BaiduConfig {
private String appId;
private String apiKey;
private String secretKey;
}
版权声明
本文为[Spilled off]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231403162847.html
边栏推荐
- JSP learning 3
- What is cloud migration? The four modes of cloud migration are?
- 捡起MATLAB的第(8)天
- 关于 background-image 渐变gradient()那些事!
- 撿起MATLAB的第(9)天
- There is a problem with the light switch from 1 to 100
- How to quickly batch create text documents?
- Algorithem_ ReverseLinkedList
- ES常用查询、排序、聚合语句
- Creation of RAID disk array and RAID5
猜你喜欢

Day (9) of picking up matlab

You need to know about cloud disaster recovery

Day (6) of picking up matlab

Force buckle - 198 raid homes and plunder houses

捡起MATLAB的第(6)天

Hypermotion cloud migration completes Alibaba cloud proprietary cloud product ecological integration certification

RecyclerView advanced use - to realize drag and drop function of imitation Alipay menu edit page

Gartner announces emerging technology research: insight into the meta universe

The biggest winner is China Telecom. Why do people dislike China Mobile and China Unicom?

Best practice of cloud migration in education industry: Haiyun Jiexun uses hypermotion cloud migration products to implement progressive migration for a university in Beijing, with a success rate of 1
随机推荐
JSP learning 3
力扣-198.打家劫舍
安装Redis并部署Redis高可用集群
Creation of RAID disk array and RAID5
ESP32编译环境的搭建
linux上启动oracle服务
JIRA screenshot
MySQL的btree索引和hash索引区别
Force buckle-746 Climb stairs with minimum cost
捡起MATLAB的第(4)天
浅谈 NFT项目的价值、破发、收割之争
Six scenarios of cloud migration
人脸识别框架之dlib
The biggest winner is China Telecom. Why do people dislike China Mobile and China Unicom?
Cloudy data flow? Disaster recovery on cloud? Last value content sharing years ago
最详细的背包问题!!!
Query the data from 2013 to 2021, and only query the data from 2020. The solution to this problem is carried out
Questions about disaster recovery? Click here
What is homebrew? And use
面试题 17.10. 主要元素