Kaynağa Gözat

qwen-v1-ocr

deason 2 ay önce
ebeveyn
işleme
9e4bd71e51

+ 114 - 0
src/main/java/com/qmth/ops/biz/ai/client/aliyun/qwen_ocr/QwenOcrClient.java

@@ -0,0 +1,114 @@
+package com.qmth.ops.biz.ai.client.aliyun.qwen_ocr;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.qmth.boot.core.ai.model.llm.ChatRole;
+import com.qmth.boot.core.ai.model.ocr.OcrType;
+import com.qmth.boot.tools.codec.CodecUtils;
+import com.qmth.boot.tools.models.ByteArray;
+import com.qmth.ops.biz.ai.client.OcrApiClient;
+import com.qmth.ops.biz.ai.client.OcrApiConfig;
+import com.qmth.ops.biz.ai.exception.ChatRequestError;
+import okhttp3.MediaType;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+public class QwenOcrClient extends OcrApiClient {
+
+    private static final Logger log = LoggerFactory.getLogger(QwenOcrClient.class);
+
+    public QwenOcrClient(OcrApiConfig config) {
+        super(config);
+    }
+
+    @Override
+    protected Request buildRequest(OcrType type, byte[] image) throws Exception {
+        Map<String, Object> request = new HashMap<>();
+        request.put("model", "qwen-vl-ocr");
+        List<Map<String, Object>> messages = new ArrayList<>();
+        Map<String, Object> message = new HashMap<>();
+        message.put("role", "user");
+        List<Map<String, Object>> contents = new ArrayList<>();
+        Map<String, Object> content1 = new HashMap<>();
+        content1.put("type", "image_url");
+        Map<String, String> urlBase64 = new HashMap<>();
+        String base64 = CodecUtils.toBase64(image);
+        urlBase64.put("url", "data:image/jpeg;base64," + base64);
+        content1.put("image_url", urlBase64);
+        // content1.put("min_pixels", 1000);
+        // content1.put("max_pixels", 1280000);
+        Map<String, Object> content2 = new HashMap<>();
+        content2.put("type", "text");
+        content2.put("text", "Read all the text in the image.");
+        contents.add(content1);
+        contents.add(content2);
+        messages.add(message);
+        message.put("content", contents);
+        request.put("messages", messages);
+
+        String json = new ObjectMapper().writeValueAsString(request);
+        log.info("request:{}", json);
+        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), json);
+        return new Request.Builder().url(getConfig().getUrl())
+                .addHeader("Authorization", "Bearer " + getConfig().getSecret())
+                .post(requestBody)
+                .build();
+    }
+
+    @Override
+    protected String buildResult(byte[] data, ObjectMapper mapper) throws IOException {
+        String json = data != null ? new String(data, StandardCharsets.UTF_8) : null;
+        log.info("response:{}", json);
+
+        QwenOcrResult result = mapper.readValue(json, QwenOcrResult.class);
+        return result.getChoices().stream().filter(choice -> choice.getMessage().getRole() == ChatRole.assistant)
+                .map(choice -> choice.getMessage().getContent()).findFirst().orElse("");
+    }
+
+    @Override
+    protected String handleError(byte[] data, int statusCode, ObjectMapper mapper) {
+        String error = data != null ? new String(data, StandardCharsets.UTF_8) : null;
+        log.info("responseError:{}", error);
+
+        if (data != null) {
+            try {
+                QwenOcrResponse response = mapper.readValue(data, QwenOcrResponse.class);
+                if (response != null && response.getError() != null) {
+                    error = response.getError().getMessage();
+                }
+            } catch (Exception e) {
+                log.warn("handleError failed! {}", e.getMessage());
+            }
+        }
+
+        switch (statusCode) {
+            case 400:
+                throw new ChatRequestError(Optional.ofNullable(error).orElse("chat request error"));
+            case 429:
+                throw new ChatRequestError(Optional.ofNullable(error).orElse("chat model rate limit exceeded"));
+            default:
+                throw new ChatRequestError(Optional.ofNullable(error).orElse("chat model error"));
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        OcrApiConfig config = new OcrApiConfig();
+        config.setUrl("https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions");
+        // config.setUrl("https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation");
+        config.setSecret("sk-xxx");
+        config.setQps(10);
+
+        File file = new File("D:\\home\\test.png");
+        byte[] image = ByteArray.fromFile(file).value();
+        QwenOcrClient client = new QwenOcrClient(config);
+        String value = client.forImage(OcrType.HANDWRITING, image);
+        System.out.println(value);
+    }
+
+}

+ 38 - 0
src/main/java/com/qmth/ops/biz/ai/client/aliyun/qwen_ocr/QwenOcrError.java

@@ -0,0 +1,38 @@
+package com.qmth.ops.biz.ai.client.aliyun.qwen_ocr;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class QwenOcrError {
+
+    private String type;
+
+    private String code;
+
+    private String message;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+}

+ 18 - 0
src/main/java/com/qmth/ops/biz/ai/client/aliyun/qwen_ocr/QwenOcrResponse.java

@@ -0,0 +1,18 @@
+package com.qmth.ops.biz.ai.client.aliyun.qwen_ocr;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class QwenOcrResponse {
+
+    private QwenOcrError error;
+
+    public QwenOcrError getError() {
+        return error;
+    }
+
+    public void setError(QwenOcrError error) {
+        this.error = error;
+    }
+
+}

+ 31 - 0
src/main/java/com/qmth/ops/biz/ai/client/aliyun/qwen_ocr/QwenOcrResult.java

@@ -0,0 +1,31 @@
+package com.qmth.ops.biz.ai.client.aliyun.qwen_ocr;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.qmth.boot.core.ai.model.llm.ChatChoice;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class QwenOcrResult {
+
+    private String id;
+
+    private List<ChatChoice> choices;
+
+    public List<ChatChoice> getChoices() {
+        return choices;
+    }
+
+    public void setChoices(List<ChatChoice> choices) {
+        this.choices = choices;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+}