话不多说 直接上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);
        }
    }
}
相关推荐
weixin_408099671 天前
2026 扑克牌识别 API 实战:识别牌值、花色、大小王(附 Python/Java/PHP 接入示例)
python·ocr·图像识别·api接口·接口开发·扑克牌识别·石榴智能
开开心心就好1 天前
内存清理工具定时自动清理开机自启动
java·开发语言·elasticsearch·ocr·excel·音视频·big data
王莎莎-MinerU1 天前
别让 Agent 重读 PDF:文档解析要交付可缓存资产
网络·数据库·人工智能·驱动开发·缓存·pdf·ocr
开开心心就好1 天前
电脑内存优化工具一键释放内存超简单
java·开发语言·macos·arcgis·ocr·excel·音视频
m0_726365832 天前
# Chrome纸牌游戏预测工具开发实战:Canvas图表识别、OCR与实时状态监控
chrome·python·游戏·贪心算法·ocr·线性回归·哈希算法
六月的翅膀2 天前
OCR:RapidOCR C++/C#
c++·ocr
molihuan2 天前
最新 Paddle-Lite Android平台编译
android·ocr·paddle·推理·端侧·paddle lite
蓝创工坊Blue Foundry3 天前
发票、凭证和对账单怎么整理成 Excel?先定义字段,再逐项复核
pdf·ocr·excel·文心一言·paddlepaddle
求真学习3 天前
字节跳动Dolphin-v2:数字 PDF 拆开读、拍照文档整页读,自建拍照文档集平均编辑距离较原始 Dolphin降低约 91%
pdf·ocr·pdf解析·字节跳动·文档解析·dolphin-v2
CodexDave3 天前
Python 自动化接单实战(四):PDF 批量提取先识别文本层还是扫描件
python·pdf·自动化·ocr·python自动化·文档处理·pdf提取