Commit eb171a063423a83a29345307d36072dd70ac18d4
1 parent
5c3224d448
Exists in
master
大模型批改
Showing
10 changed files
with
141 additions
and
12 deletions
Show diff stats
app/src/main/java/com/hjx/parent/JudgeActivity.java
... | ... | @@ -4,8 +4,10 @@ import android.annotation.SuppressLint; |
4 | 4 | import android.graphics.Bitmap; |
5 | 5 | import android.graphics.Rect; |
6 | 6 | import android.os.Bundle; |
7 | +import android.util.Log; | |
7 | 8 | |
8 | 9 | import com.bumptech.glide.Glide; |
10 | +import com.hjx.parent.api.JudgeRepository; | |
9 | 11 | import com.hjx.parent.databinding.ActivityJudgeBinding; |
10 | 12 | import com.hjx.parent.databinding.LayoutJudgeRectBinding; |
11 | 13 | import com.hjx.parent.rx.BaseRxActivity; |
... | ... | @@ -15,6 +17,7 @@ import java.io.File; |
15 | 17 | import java.util.ArrayList; |
16 | 18 | import java.util.List; |
17 | 19 | |
20 | +import io.reactivex.Observable; | |
18 | 21 | import io.reactivex.Single; |
19 | 22 | import top.zibin.luban.Luban; |
20 | 23 | |
... | ... | @@ -62,6 +65,41 @@ public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> { |
62 | 65 | LayoutJudgeRectBinding vb = showRect(rect); |
63 | 66 | mList.add(new JudgeCut(i, bitmap, rect, vb)); |
64 | 67 | } |
68 | + | |
69 | + judge(); | |
70 | + } | |
71 | + | |
72 | + @SuppressLint("CheckResult") | |
73 | + private void judge() { | |
74 | + showLoadingDialog(""); | |
75 | + Observable.fromIterable(mList) | |
76 | + .map(it -> { | |
77 | + if (it.url != null && !it.url.isEmpty()) return it; | |
78 | + String base64 = CutUtil.bitmapToBase64(it.bitmap, true); | |
79 | + it.url = base64; | |
80 | + return it; | |
81 | + }) | |
82 | + .flatMap(it -> JudgeRepository.singleJudge(it.url) | |
83 | + .map(result -> { | |
84 | + it.correctResult = result; | |
85 | + return it; | |
86 | + }) | |
87 | + .toObservable() | |
88 | + ) | |
89 | + .compose(transform()) | |
90 | + .subscribe(it -> { | |
91 | + if (it.correctResult == 1) { | |
92 | + it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct); | |
93 | + it.vb.getRoot().setSelected(false); | |
94 | + } else if (it.correctResult == 2) { | |
95 | + it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong); | |
96 | + it.vb.getRoot().setSelected(true); | |
97 | + } | |
98 | + }, th -> { | |
99 | + cancelLoadingDialog(); | |
100 | + Log.e(getClass().getName(), "", th); | |
101 | + }, this::cancelLoadingDialog) | |
102 | + ; | |
65 | 103 | } |
66 | 104 | |
67 | 105 | private LayoutJudgeRectBinding showRect(Rect rect) { |
... | ... | @@ -111,6 +149,7 @@ public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> { |
111 | 149 | final Rect rect; |
112 | 150 | final LayoutJudgeRectBinding vb; |
113 | 151 | |
152 | + String url; | |
114 | 153 | int correctResult = 0; |
115 | 154 | |
116 | 155 | public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) { | ... | ... |
app/src/main/java/com/hjx/parent/api/ChatApi.java
1 | 1 | package com.hjx.parent.api; |
2 | 2 | |
3 | +import io.reactivex.Single; | |
4 | +import retrofit2.http.Body; | |
3 | 5 | import retrofit2.http.Header; |
4 | 6 | import retrofit2.http.POST; |
5 | 7 | import retrofit2.http.Url; |
6 | 8 | |
7 | 9 | public interface ChatApi { |
8 | 10 | @POST |
9 | - void aiChat(@Url String url, @Header("Authorization") String token); | |
11 | + Single<ChatResponse> aiChat( | |
12 | + @Url String url, | |
13 | + @Header("Authorization") String token, | |
14 | + @Body ChatRequest body | |
15 | + ); | |
16 | + | |
10 | 17 | } | ... | ... |
app/src/main/java/com/hjx/parent/api/ChatMessage.java
... | ... | @@ -21,7 +21,8 @@ public class ChatMessage { |
21 | 21 | items.add(new ContentItem(ContentItem.TYPE_TEXT, text)); |
22 | 22 | } |
23 | 23 | for (String it: urls) { |
24 | - items.add(new ContentItem(ContentItem.TYPE_IMAGE, it)); | |
24 | + ContentItem.ContentImage image = new ContentItem.ContentImage(it); | |
25 | + items.add(new ContentItem(ContentItem.TYPE_IMAGE, image)); | |
25 | 26 | } |
26 | 27 | return new ChatMessage(role, items); |
27 | 28 | } | ... | ... |
app/src/main/java/com/hjx/parent/api/ChatRequest.java
... | ... | @@ -6,4 +6,10 @@ public class ChatRequest { |
6 | 6 | public String model; |
7 | 7 | public List<ChatMessage> messages; |
8 | 8 | public boolean stream; |
9 | + | |
10 | + public ChatRequest(String model, List<ChatMessage> messages) { | |
11 | + this.model = model; | |
12 | + this.messages = messages; | |
13 | + this.stream = false; | |
14 | + } | |
9 | 15 | } | ... | ... |
app/src/main/java/com/hjx/parent/api/ContentItem.java
app/src/main/java/com/hjx/parent/api/JudgeRepository.java
... | ... | @@ -0,0 +1,55 @@ |
1 | +package com.hjx.parent.api; | |
2 | + | |
3 | +import android.annotation.SuppressLint; | |
4 | + | |
5 | +import com.google.gson.Gson; | |
6 | +import com.prws.common.net.NetWorks; | |
7 | + | |
8 | +import java.util.ArrayList; | |
9 | +import java.util.List; | |
10 | + | |
11 | +import io.reactivex.Single; | |
12 | +import retrofit2.Retrofit; | |
13 | + | |
14 | +public class JudgeRepository { | |
15 | + private static final Gson gson = new Gson(); | |
16 | + private static final ChatApi api; | |
17 | + static { | |
18 | + Retrofit retrofit = NetWorks.retrofit; | |
19 | + api = retrofit.create(ChatApi.class); | |
20 | + } | |
21 | + | |
22 | + | |
23 | + public static Single<Integer> singleJudge(String url) { | |
24 | + List<ChatMessage> messages = new ArrayList<>(); | |
25 | + messages.add(ChatMessage.fromImage("system", setting, url)); | |
26 | + | |
27 | + return api.aiChat(JudgeRepository.url, token, new ChatRequest(model, messages)) | |
28 | + .map(response -> { | |
29 | + if (response.choices == null) return null; | |
30 | + return response.choices.stream().findFirst() | |
31 | + .map(it -> it.message) | |
32 | + .map(ChatMessage::getTextContent) | |
33 | + .orElse(null); | |
34 | + }) | |
35 | + .map(json -> { | |
36 | + JudgeResult result = gson.fromJson(json, JudgeResult.class); | |
37 | + return result.result; | |
38 | + }) | |
39 | + ; | |
40 | + } | |
41 | + | |
42 | + | |
43 | + private static final String model = "doubao-1-5-thinking-vision-pro-250428"; | |
44 | + private static final String url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"; | |
45 | + private static final String token = "Bearer a877087e-bb74-471b-8f2a-01e6b2220699"; | |
46 | + private static final String setting = | |
47 | + "批改图片中的题目, 判断作答是否正确,并以Json格式返回结果,需要包含以下字段: \n" + | |
48 | + "result(批改结果, 枚举 0:不确定; 1:正确; 2:错误; 3:未作答).\n" + | |
49 | + "Json示例(供参考,无需复制): {\"result\": 1}\n" + | |
50 | + "一个图片中一般只会有一个题目, 返回一个结果即可."; | |
51 | + | |
52 | + private static class JudgeResult { | |
53 | + public int result; | |
54 | + } | |
55 | +} | ... | ... |
app/src/main/java/com/hjx/parent/utils/CutUtil.java
... | ... | @@ -5,6 +5,7 @@ import android.graphics.Bitmap; |
5 | 5 | import android.graphics.Canvas; |
6 | 6 | import android.graphics.Color; |
7 | 7 | import android.graphics.Paint; |
8 | +import android.util.Base64; | |
8 | 9 | import android.view.View; |
9 | 10 | import android.view.ViewTreeObserver; |
10 | 11 | |
... | ... | @@ -12,6 +13,8 @@ import com.bumptech.glide.Glide; |
12 | 13 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; |
13 | 14 | import com.hjx.parent.function.Function1; |
14 | 15 | |
16 | +import java.io.ByteArrayOutputStream; | |
17 | + | |
15 | 18 | public class CutUtil { |
16 | 19 | |
17 | 20 | public static float[] measureBitmap(View view, Bitmap bitmap) { |
... | ... | @@ -72,4 +75,16 @@ public class CutUtil { |
72 | 75 | } |
73 | 76 | ); |
74 | 77 | } |
78 | + | |
79 | + public static byte[] bitmapToByteArray(Bitmap bitmap) { | |
80 | + ByteArrayOutputStream output = new ByteArrayOutputStream(); | |
81 | + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output); | |
82 | + return output.toByteArray(); | |
83 | + } | |
84 | + | |
85 | + public static String bitmapToBase64(Bitmap bitmap, Boolean usePrefix) { | |
86 | + String base64 = Base64.encodeToString(bitmapToByteArray(bitmap), Base64.NO_WRAP); | |
87 | + if (usePrefix) return "data:image/jpeg;base64," + base64; | |
88 | + else return base64; | |
89 | + } | |
75 | 90 | } | ... | ... |
app/src/main/res/drawable/png_ic_judge_wrong.png
1.12 KB
libs/common/src/main/java/com/prws/common/net/NetWorks.java
... | ... | @@ -38,6 +38,7 @@ import okhttp3.RequestBody; |
38 | 38 | import okhttp3.ResponseBody; |
39 | 39 | import retrofit2.Call; |
40 | 40 | import retrofit2.Callback; |
41 | +import retrofit2.Retrofit; | |
41 | 42 | import retrofit2.http.Body; |
42 | 43 | import retrofit2.http.GET; |
43 | 44 | import retrofit2.http.Header; |
... | ... | @@ -58,7 +59,8 @@ import retrofit2.http.Url; |
58 | 59 | */ |
59 | 60 | public class NetWorks extends RetrofitUtils { |
60 | 61 | //服务器路径 |
61 | - public static final NetService service_url = getMachineRetrofit(BuildConfig.SERVER_URL).create(NetService.class); | |
62 | + public static final Retrofit retrofit = getMachineRetrofit(BuildConfig.SERVER_URL); | |
63 | + public static final NetService service_url = retrofit.create(NetService.class); | |
62 | 64 | |
63 | 65 | //设缓存有效期为1天 |
64 | 66 | protected static final long CACHE_STALE_SEC = 60 * 60 * 24 * 1; | ... | ... |
libs/common/src/main/java/com/prws/common/net/SignInterceptor.java
1 | 1 | package com.prws.common.net; |
2 | 2 | |
3 | +import androidx.annotation.NonNull; | |
4 | + | |
5 | +import com.prws.common.BuildConfig; | |
3 | 6 | import com.prws.common.utils.SharedPreferencesUtil; |
4 | 7 | |
5 | 8 | import org.apache.commons.codec.binary.Hex; |
... | ... | @@ -14,23 +17,20 @@ import okhttp3.Request; |
14 | 17 | import okhttp3.Response; |
15 | 18 | |
16 | 19 | public class SignInterceptor implements Interceptor { |
20 | + @NonNull | |
17 | 21 | @Override |
18 | 22 | public Response intercept(Chain chain) throws IOException { |
19 | -// String appId = "1"; | |
20 | -// String APP_SECRET = "a839c40e04477d43705a64ba9db23b0dba969df360c3e428add85a6f5b8d0622"; | |
21 | -// String timestamp = String.valueOf(new Date().getTime()); | |
22 | -// String nonce = String.valueOf(new Random().nextInt(10000)); | |
23 | -// String sign = DigestUtils.md5Hex(appId + APP_SECRET + timestamp + nonce); // yidao板子报错 采用如下代码 | |
24 | -// byte[] signBytes = DigestUtils.md5(appId + APP_SECRET + timestamp + nonce); | |
25 | -// String sign = new String(Hex.encodeHex(signBytes)); | |
23 | + String host = BuildConfig.SERVER_URL; | |
24 | + if (!chain.request().url().toString().startsWith(host)) { | |
25 | + return chain.proceed(chain.request()); | |
26 | + } | |
27 | + | |
26 | 28 | String token = (String) SharedPreferencesUtil.getData("token",""); |
27 | 29 | Request.Builder requestBuilder = chain.request().newBuilder(); |
28 | 30 | if (token != null && token.length() > 0) { |
29 | 31 | requestBuilder = chain.request().newBuilder() |
30 | 32 | .header("Authorization", token); |
31 | 33 | } |
32 | -// .header("Content-Type","application/json"); | |
33 | - | |
34 | 34 | return chain.proceed(requestBuilder.build()); |
35 | 35 | } |
36 | 36 | } | ... | ... |