package com.utils; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import org.json.JSONArray; import org.json.JSONObject; import com.baidu.aip.ocr.AipOcr; import com.baidu.aip.imageclassify.AipImageClassify; /** * 百度AI服务工具类 * * 核心职责:集成百度地图和百度AI的各项服务功能 * * 功能模块: * 1. 百度地图 - 逆地理编码服务 * 2. 百度AI - OCR文字识别 * 3. 百度AI - 图像识别(动物、菜品、植物) * 4. 百度AI - 访问令牌管理 * * 技术特点: * - 基于百度AI Java SDK * - 支持多种AI能力调用 * - 提供统一的服务接口 * * 使用场景: * - 地理位置解析 * - 图片文字识别 * - 图像内容识别 * - AI能力集成 */ public class BaiduUtil { // 百度AI应用配置(示例配置,实际使用时应从配置文件中读取) public static final String APP_ID = "29917330"; public static final String API_KEY = "yMnHy1guHZRzGhXB7BILdktB"; public static final String SECRET_KEY = "1oHG8X0yizyZmIwj3bZygG470b648iE1"; // OCR客户端单例 private static AipOcr ocrClient = null; /** * 根据经纬度获取省市区信息(逆地理编码) * 使用百度地图API将经纬度坐标转换为具体地址信息 * * @param key 百度地图API Key * @param lng 经度 * @param lat 纬度 * @return 包含省市区街道信息的Map,解析失败返回null */ public static Map getCityByLonLat(String key, String lng, String lat) { String location = lat + "," + lng; try { // 拼装百度逆地理编码API URL String url = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=" + key + "&output=json&coordtype=wgs84ll&location=" + location; // 发送HTTP GET请求 String result = HttpClientUtils.doGet(url); JSONObject o = new JSONObject(result); // 解析返回的地址组件信息 Map area = new HashMap<>(); JSONObject addressComponent = o.getJSONObject("result").getJSONObject("addressComponent"); area.put("province", addressComponent.getString("province")); // 省份 area.put("city", addressComponent.getString("city")); // 城市 area.put("district", addressComponent.getString("district")); // 区县 area.put("street", addressComponent.getString("street")); // 街道 return area; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 获取百度AI访问令牌 * 该token有一定的有效期,需要自行管理,当失效时需重新获取 * * @param ak 百度云官网获取的 API Key * @param sk 百度云官网获取的 Secret Key * @return access_token 访问令牌 */ public static String getAuth(String ak, String sk) { // 获取token地址 String authHost = "https://aip.baidubce.com/oauth/2.0/token?"; String getAccessTokenUrl = authHost // 1. grant_type为固定参数 + "grant_type=client_credentials" // 2. 官网获取的 API Key + "&client_id=" + ak // 3. 官网获取的 Secret Key + "&client_secret=" + sk; try { URL realUrl = new URL(getAccessTokenUrl); // 打开和URL之间的连接 HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection(); connection.setRequestMethod("GET"); connection.connect(); // 获取所有响应头字段(用于调试) Map> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { System.err.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String result = ""; String line; while ((line = in.readLine()) != null) { result += line; } /** * 返回结果示例: * { * "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567", * "expires_in": 2592000 * } */ System.err.println("result:" + result); org.json.JSONObject jsonObject = new org.json.JSONObject(result); String access_token = jsonObject.getString("access_token"); return access_token; } catch (Exception e) { System.err.printf("获取token失败!"); e.printStackTrace(System.err); } return null; } /** * 识别图片上的文本内容,转换成文字字符串返回 * 使用百度OCR高精度文字识别接口 * * @param imagePath 图片文件的路径 * @param isNewline 是否保留换行符(true:每行文字后加换行符,false:所有文字连续) * @return 识别出的文字字符串,识别失败返回null */ public static String generalString(String imagePath, boolean isNewline) { try { HashMap options = new HashMap(); options.put("language_type", "CHN_ENG"); // CHN_ENG:中英文混合, ENG:英文 options.put("detect_direction", "true"); // 是否检测图像朝向,默认不检测 options.put("detect_language", "true"); // 是否检测语言,默认不检测 options.put("probability", "false"); // 是否返回识别结果中每一行的置信度 // 初始化OCR客户端(单例模式) if (ocrClient == null) { ocrClient = new AipOcr(APP_ID, API_KEY, SECRET_KEY); // 设置连接超时和读取超时 ocrClient.setConnectionTimeoutInMillis(5000); // 连接超时5秒 ocrClient.setSocketTimeoutInMillis(60000); // 读取超时60秒 } // 调用通用文字识别(高精度版)接口 JSONObject jsonObject = ocrClient.basicAccurateGeneral(imagePath, options); String result = mergeString(jsonObject, isNewline); return result; } catch (Exception ex) { ex.printStackTrace(); } return null; } /** * 合并OCR识别结果 * 将JSON格式的识别结果合并为字符串 * * @param jsonObject OCR识别返回的JSON对象 * @param isNewline 是否保留换行符 * @return 合并后的字符串 */ private static String mergeString(JSONObject jsonObject, boolean isNewline) { if (jsonObject == null) { return ""; } // 检查是否包含识别结果 if (jsonObject.has("words_result") && jsonObject.has("words_result_num")) { int wordsResultNum = jsonObject.getInt("words_result_num"); if (wordsResultNum > 0) { StringBuilder sb = new StringBuilder(); JSONArray jsonArray = jsonObject.getJSONArray("words_result"); int len = jsonArray.length(); for (int i = 0; i < len; i++) { JSONObject obj = (JSONObject) jsonArray.get(i); if (isNewline) { sb.append(obj.get("words") + "\n"); // 每行文字后加换行符 } else { sb.append(obj.get("words")); // 所有文字连续 } } return sb.toString(); } } else { // 如果没有识别结果,返回原始JSON字符串 return jsonObject.toString(); } return null; } /** * 动物识别 * 识别图片中的动物种类 * * @param imgPath 图片路径 * @return 识别结果的JSON对象 */ public static JSONObject animalDetect(String imgPath) { // 初始化图像分类客户端 AipImageClassify aic = new AipImageClassify(APP_ID, API_KEY, SECRET_KEY); // 设置请求参数 HashMap params = new HashMap(); params.put("baike_num", "1"); // 返回百科信息的数量 // 调用动物识别接口 JSONObject res = aic.animalDetect(imgPath, params); System.out.println(res.toString(2)); // 格式化输出结果 return res; } /** * 菜品识别 * 识别图片中的菜品类型 * * @param imgPath 图片路径 * @return 识别结果的JSON对象 */ public static JSONObject dishDetect(String imgPath) { // 初始化图像分类客户端 AipImageClassify aic = new AipImageClassify(APP_ID, API_KEY, SECRET_KEY); // 设置请求参数 HashMap params = new HashMap(); params.put("baike_num", "1"); // 返回百科信息的数量 // 调用菜品识别接口 JSONObject res = aic.dishDetect(imgPath, params); System.out.println(res.toString(2)); // 格式化输出结果 return res; } /** * 植物识别 * 识别图片中的植物种类 * * @param imgPath 图片路径 * @return 识别结果的JSON对象 */ public static JSONObject plantDetect(String imgPath) { // 初始化图像分类客户端 AipImageClassify aic = new AipImageClassify(APP_ID, API_KEY, SECRET_KEY); // 设置请求参数 HashMap params = new HashMap(); params.put("baike_num", "1"); // 返回百科信息的数量 // 调用植物识别接口 JSONObject res = aic.plantDetect(imgPath, params); System.out.println(res.toString(2)); // 格式化输出结果 return res; } // 可以添加的增强方法: /** * 通用物体识别 * 识别图片中的通用物体 * * @param imgPath 图片路径 * @return 识别结果的JSON对象 */ public static JSONObject advancedGeneral(String imgPath) { AipImageClassify aic = new AipImageClassify(APP_ID, API_KEY, SECRET_KEY); JSONObject res = aic.advancedGeneral(imgPath, new HashMap()); System.out.println(res.toString(2)); return res; } /** * 身份证识别 * 识别身份证图片上的信息 * * @param imgPath 身份证图片路径 * @param idCardSide 身份证正反面(front:正面, back:反面) * @return 识别结果的JSON对象 */ public static JSONObject idcard(String imgPath, String idCardSide) { if (ocrClient == null) { ocrClient = new AipOcr(APP_ID, API_KEY, SECRET_KEY); } HashMap options = new HashMap(); options.put("detect_direction", "true"); options.put("detect_risk", "false"); JSONObject res = ocrClient.idcard(imgPath, idCardSide, options); return res; } }