话不多说 直接上glm-ocr的工具类

复制代码
    <dependency>
            <groupId>ai.z.openapi</groupId>
            <artifactId>zai-sdk</artifactId>
            <version>0.3.3</version>
        </dependency>
复制代码
import ai.z.openapi.ZhipuAiClient;
import ai.z.openapi.service.layoutparsing.LayoutParsingCreateParams;
import ai.z.openapi.service.layoutparsing.LayoutParsingResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * GLM-OCR工具类
 * 用于识别证书图片中的文字内容
 *
 * API文档:https://docs.bigmodel.cn/llms.txt
 */
@Slf4j
@Component
public class GLMOCRUtil {

    @Value("${zhipu.ai.api-key}")
    private String apiKey;

    /**
     * 使用GLM-OCR识别图片中的文字
     *
     * @param imageUrl OSS上的图片URL
     * @return 识别的文字内容
     */
    public String recognizeText(String imageUrl) {
        try {
            log.info("开始OCR识别,图片URL: {}", imageUrl);

            // 1. 初始化客户端
            ZhipuAiClient client = ZhipuAiClient.builder()
                    .ofZHIPU()
                    .apiKey(apiKey)
                    .build();

            // 2. 设置模型
            String model = "glm-ocr";

            // 3. 创建布局解析请求
            LayoutParsingCreateParams params = LayoutParsingCreateParams.builder()
                    .model(model)
                    .file(imageUrl)
                    .build();

            // 4. 发送请求
            LayoutParsingResponse response = client.layoutParsing().layoutParsing(params);
            // 5. 处理响应
            log.info("收到OCR响应,开始处理...");
            log.info("响应是否成功: {}", response.isSuccess());

            // 打印响应对象的详细信息
            log.info("响应对象类型: {}", response.getClass().getName());
            log.info("响应对象所有方法:");
            for (java.lang.reflect.Method method : response.getClass().getMethods()) {
                log.info("  - {} {}", method.getReturnType().getSimpleName(), method.getName());
            }

            if (response != null && response.isSuccess()) {
                // 提取文字内容
                String text = extractTextFromResponse(response);

                if (text != null && !text.isEmpty()) {
                    log.info("OCR识别成功,识别到{}个字符", text.length());
                    log.debug("OCR识别内容预览: {}", text.length() > 200 ? text.substring(0, 200) + "..." : text);
                    return text;
                } else {
                    log.warn("OCR识别结果为空");
                    // 即使结果为空,也尝试打印响应内容
                    log.warn("响应toString: {}", response.toString());
                    return "";
                }
            } else {
                String msg = response != null ? response.getMsg() : "响应为空";
                log.error("OCR识别失败: {}", msg);
                throw new RuntimeException("OCR识别失败: " + msg);
            }

        } catch (Exception e) {
            log.error("OCR识别异常", e);
            throw new RuntimeException("OCR识别失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从响应中提取文字内容
     *
     * 根据官方文档,响应包含 md_results 字段
     */
    private String extractTextFromResponse(LayoutParsingResponse response) {
        try {
            log.info("开始提取OCR识别结果...");
            log.info("响应类型: {}", response.getClass().getName());

            // 尝试使用SDK提供的方法
            // 根据官方文档,应该有 getMd_results() 方法
            try {
                // 方式1:直接调用getMd_results方法
                java.lang.reflect.Method mdResultsMethod = response.getClass().getMethod("getMd_results");
                Object mdResults = mdResultsMethod.invoke(response);
                if (mdResults != null) {
                    String text = mdResults.toString();
                    log.info("通过getMd_results方法获取到OCR结果,长度: {}", text.length());
                    return text;
                }
            } catch (NoSuchMethodException e) {
                log.warn("getMd_results方法不存在,尝试其他方法");
            }

            // 方式2:尝试getData方法
            try {
                java.lang.reflect.Method dataMethod = response.getClass().getMethod("getData");
                Object data = dataMethod.invoke(response);
                if (data != null) {
                    log.info("getData返回: {}", data.getClass().getName());
                    // 如果getData返回的是对象,尝试获取其md_results
                    try {
                        java.lang.reflect.Method dataMdMethod = data.getClass().getMethod("getMd_results");
                        Object dataMd = dataMdMethod.invoke(data);
                        if (dataMd != null) {
                            String text = dataMd.toString();
                            log.info("通过getData().getMd_results获取到OCR结果,长度: {}", text.length());
                            return text;
                        }
                    } catch (Exception ex) {
                        log.warn("getData().getMd_results失败: {}", ex.getMessage());
                    }
                    return data.toString();
                }
            } catch (NoSuchMethodException e) {
                log.warn("getData方法不存在");
            }

            // 方式3:获取响应JSON字符串
            try {
                java.lang.reflect.Method toStringMethod = response.getClass().getMethod("toString");
                Object strResult = toStringMethod.invoke(response);
                log.info("响应toString结果: {}", strResult);

                // 尝试从toString结果中解析
                if (strResult != null && strResult.toString().contains("md_results")) {
                    // 简单解析JSON
                    String jsonStr = strResult.toString();
                    int mdIndex = jsonStr.indexOf("md_results");
                    if (mdIndex > 0) {
                        int startQuote = jsonStr.indexOf("\"", mdIndex + 11);
                        int endQuote = jsonStr.indexOf("\"", startQuote + 1);
                        if (startQuote > 0 && endQuote > startQuote) {
                            String text = jsonStr.substring(startQuote + 1, endQuote);
                            log.info("从toString解析到OCR结果,长度: {}", text.length());
                            return text;
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("解析toString失败: {}", e.getMessage());
            }

            log.error("所有提取方法都失败");
            return null;

        } catch (Exception e) {
            log.error("提取OCR结果异常", e);
            return null;
        }
    }

    /**
     * 使用GLM-OCR识别本地文件(Base64)
     *
     * @param imageBase64 图片Base64编码
     * @return 识别的文字内容
     */
    public String recognizeTextFromBase64(String imageBase64) {
        try {
            log.info("开始OCR识别(Base64方式),数据长度: {} bytes", imageBase64.length());

            // 1. 初始化客户端
            ZhipuAiClient client = ZhipuAiClient.builder()
                    .ofZHIPU()
                    .apiKey(apiKey)
                    .build();

            // 2. 设置模型
            String model = "glm-ocr";

            // 3. 创建布局解析请求(使用Base64)
            LayoutParsingCreateParams params = LayoutParsingCreateParams.builder()
                    .model(model)
                    .file(imageBase64)
                    .build();

            // 4. 发送请求
            LayoutParsingResponse response = client.layoutParsing().layoutParsing(params);

            // 5. 处理响应
            if (response != null && response.isSuccess()) {
                // 提取文字内容
                String text = extractTextFromResponse(response);

                if (text != null && !text.isEmpty()) {
                    log.info("OCR识别成功,识别到{}个字符", text.length());
                    return text;
                } else {
                    log.warn("OCR识别结果为空");
                    return "";
                }
            } else {
                String msg = response != null ? response.getMsg() : "响应为空";
                log.error("OCR识别失败: {}", msg);
                throw new RuntimeException("OCR识别失败: " + msg);
            }

        } catch (Exception e) {
            log.error("OCR识别异常", e);
            throw new RuntimeException("OCR识别失败: " + e.getMessage(), e);
        }
    }
}
相关推荐
无心水5 小时前
13、云端OCR终极指南|百度/阿里/腾讯API高精度文字提取实战
百度·架构·pdf·ocr·dubbo·pdf解析·pdf抽取
Chef_Chen16 小时前
论文解读:不需要OCR,不需要描述生成——ColPali重构了文档检索的底层逻辑
重构·ocr
新缸中之脑1 天前
Chandra:商业OCR的终结者
ocr
MarkHD2 天前
RPA进阶实战:从零打造智能票据处理机器人——OCR识别、Excel自动填报与邮件通知全流程
机器人·ocr·rpa
叫我黎大侠2 天前
.NET 实战:调用千问视觉模型实现 OCR(车票识别完整教程)
阿里云·ai·c#·ocr·asp.net·.net·.netcore
石榴树下的七彩鱼2 天前
OCR 识别接口哪个好?2026 年主流 OCR API 对比评测(附免费在线体验)
图像处理·人工智能·后端·计算机视觉·ocr·api·文字识别
AI人工智能+2 天前
表格识别技术通过深度学习与计算机视觉,实现复杂表格的自动化解析与结构化输出
深度学习·计算机视觉·ocr·表格识别
石榴树下的七彩鱼3 天前
身份证 OCR 识别 API 接入详解(Python / Java 示例)
java·开发语言·人工智能·后端·python·ocr·api
石榴树下的七彩鱼3 天前
Python OCR 文字识别 API 接入完整教程
开发语言·人工智能·后端·python·ocr·api·图片识别