Compare View

switch
from
...
to
 
Commits (5)
Showing 36 changed files   Show diff stats
.idea/inspectionProfiles/Project_Default.xml
... ... @@ -6,5 +6,10 @@
6 6 <option name="m_reportAllNonLibraryCalls" value="false" />
7 7 <option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.AbstractStringBuilder,capacity|codePointAt|codePointBefore|codePointCount|indexOf|lastIndexOf|offsetByCodePoints|substring|subSequence,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigDecimal,.*,java.math.BigInteger,.*,java.net.InetAddress,.*,java.net.URI,.*,java.nio.channels.AsynchronousChannelGroup,.*,java.nio.channels.Channel,isOpen,java.nio.channels.FileChannel,open|map|lock|tryLock|write,java.nio.channels.ScatteringByteChannel,read,java.nio.channels.SocketChannel,open|socket|isConnected|isConnectionPending,java.util.Arrays,.*,java.util.Collections,(?!addAll).*,java.util.List,of,java.util.Map,of|ofEntries|entry,java.util.Set,of,java.util.UUID,.*,java.util.concurrent.BlockingQueue,offer|remove,java.util.concurrent.CountDownLatch,await|getCount,java.util.concurrent.ExecutorService,awaitTermination|isShutdown|isTerminated,java.util.concurrent.ForkJoinPool,awaitQuiescence,java.util.concurrent.Semaphore,tryAcquire|availablePermits|isFair|hasQueuedThreads|getQueueLength|getQueuedThreads,java.util.concurrent.locks.Condition,await|awaitNanos|awaitUntil,java.util.concurrent.locks.Lock,tryLock|newCondition,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*,java.util.stream.DoubleStream,.*,java.util.stream.IntStream,.*,java.util.stream.LongStream,.*,java.util.stream.Stream,.*" />
8 8 </inspection_tool>
  9 + <inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
  10 + <inspection_tool class="UnnecessaryLocalVariable" enabled="false" level="WARNING" enabled_by_default="false">
  11 + <option name="m_ignoreImmediatelyReturnedVariables" value="false" />
  12 + <option name="m_ignoreAnnotatedVariables" value="false" />
  13 + </inspection_tool>
9 14 </profile>
10 15 </component>
11 16 \ No newline at end of file
... ...
... ... @@ -97,4 +97,9 @@ dependencies {
97 97  
98 98 implementation 'com.jakewharton:butterknife:10.2.3'
99 99 annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
  100 +
  101 +
  102 + /** 鲁班压缩 */
  103 + implementation 'top.zibin:Luban:1.1.8'
  104 +
100 105 }
101 106 \ No newline at end of file
... ...
app/src/main/AndroidManifest.xml
... ... @@ -144,6 +144,7 @@
144 144 <category android:name="android.intent.category.LAUNCHER" />
145 145 </intent-filter>
146 146 </activity>
  147 + <activity android:name=".JudgeActivity" />
147 148  
148 149 <provider
149 150 android:name="androidx.core.content.FileProvider"
... ...
app/src/main/java/com/hjx/parent/ImageActivity.java
... ... @@ -24,11 +24,13 @@ import com.google.gson.Gson;
24 24 import com.google.gson.JsonObject;
25 25 import com.hjx.parent.adapter.ImageAdapter;
26 26 import com.hjx.parent.databinding.ActivityImageBinding;
  27 +import com.hjx.parent.databinding.ItemImageBinding;
27 28 import com.hjx.parent.dialog.AddHomeworkDialog;
28 29 import com.hjx.parent.dialog.ErrorInputDialog;
29 30 import com.hjx.parent.dialog.PhotoViewDialog;
30 31 import com.hjx.parent.dialog.TipDialog;
31 32 import com.hjx.parent.rx.BaseRxActivity;
  33 +import com.hjx.parent.utils.CutUtil;
32 34 import com.prws.common.bean.CutPicBean;
33 35 import com.prws.common.bean.ImageBean;
34 36 import com.prws.common.bean.TopicBean;
... ... @@ -40,16 +42,15 @@ import com.xiasuhuei321.loadingdialog.view.LoadingDialog;
40 42 import java.io.File;
41 43 import java.util.ArrayList;
42 44 import java.util.List;
  45 +import java.util.stream.Collectors;
43 46  
44 47 import io.reactivex.Observer;
  48 +import io.reactivex.Single;
45 49 import io.reactivex.disposables.Disposable;
46   -import retrofit2.Call;
47   -import retrofit2.Callback;
48   -import retrofit2.Response;
49 50  
50 51 public class ImageActivity extends BaseRxActivity<ActivityImageBinding> implements View.OnClickListener {
51 52  
52   - private List<String> images = new ArrayList<>();
  53 + private final List<String> images = new ArrayList<>();
53 54 private ImageAdapter imageAdapter;
54 55 private List<ImageBean> list = new ArrayList<>();
55 56 private String filePath;
... ... @@ -57,12 +58,30 @@ public class ImageActivity extends BaseRxActivity&lt;ActivityImageBinding&gt; implemen
57 58 private int type = 0;
58 59 private AddHomeworkDialog addHomeworkDialog;
59 60  
  61 + @SuppressLint("CheckResult")
60 62 @Override
61 63 public void initView(Bundle savedInstanceState) {
62 64 type = getIntent().getIntExtra("type", 0);
63 65 binding.tvSave.setText(type == 0 ? "保存错题" : "录入题目");
64 66  
65   - images = getIntent().getStringArrayListExtra("images");
  67 + List<String> originList = getIntent().getStringArrayListExtra("images");
  68 + List<String> originListFinal = originList == null ? new ArrayList<>() : originList;
  69 + Single.fromCallable(() -> CutUtil.compressAllSync(this, originListFinal, 200))
  70 + .map(it -> it.stream().map(File::getAbsolutePath).collect(Collectors.toList()))
  71 + .compose(transformSingle())
  72 + .subscribe((it, throwable) -> {
  73 + if (throwable != null) Log.e(getClass().getName(), "", throwable);
  74 + images.clear();
  75 + if (it == null) {
  76 + images.addAll(originListFinal);
  77 + } else {
  78 + images.addAll(it);
  79 + }
  80 + start();
  81 + });
  82 + }
  83 +
  84 + private void start() {
66 85 if (images == null || images.size() <= 1) {
67 86 binding.rlPrevious.setVisibility(View.GONE);
68 87 binding.rlNext.setVisibility(View.GONE);
... ... @@ -82,24 +101,18 @@ public class ImageActivity extends BaseRxActivity&lt;ActivityImageBinding&gt; implemen
82 101 @Override
83 102 public void onPageSelected(int position) {
84 103 if (list.get(position).getCuts() == null) {
85   -// binding.ivPrevious.setEnabled(false);
86   -// binding.ivNext.setEnabled(false);
87 104 clearText();
88 105 }
89 106 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size());
90 107 if (position == 0) {
91 108 binding.ivPrevious.setImageResource(R.mipmap.ic_previous_gray);
92   -// binding.ivPrevious.setEnabled(true);
93 109 } else {
94 110 binding.ivPrevious.setImageResource(R.mipmap.ic_previous);
95   -// binding.ivPrevious.setEnabled(false);
96 111 }
97 112 if (position == list.size() - 1) {
98 113 binding.ivNext.setImageResource(R.mipmap.ic_next_gray);
99   -// binding.ivNext.setEnabled(true);
100 114 } else {
101 115 binding.ivNext.setImageResource(R.mipmap.ic_next);
102   -// binding.ivNext.setEnabled(false);
103 116 }
104 117 super.onPageSelected(position);
105 118 }
... ... @@ -116,6 +129,62 @@ public class ImageActivity extends BaseRxActivity&lt;ActivityImageBinding&gt; implemen
116 129 ImageBean data = list.get(binding.viewPager.getCurrentItem());
117 130 new PhotoViewDialog(this).show(data.source);
118 131 });
  132 +
  133 + binding.btnJudge.setVisibility(type == 0 ? View.VISIBLE : View.GONE);
  134 + binding.btnJudge.setOnClickListener(v -> {
  135 + goJudge();
  136 + });
  137 + }
  138 +
  139 + private void goJudge() {
  140 + if (list.isEmpty()) return;
  141 + int position = binding.viewPager.getCurrentItem();
  142 + ImageBean imageBean = list.get(position);
  143 + Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath());
  144 + if (bitmap == null || imageBean.getCuts() == null) {
  145 + showToast("请先框选题目");
  146 + return;
  147 + }
  148 + ItemImageBinding ib = imageAdapter.viewArray.get(position);
  149 + if (ib == null) {
  150 + showToast("出错");
  151 + return;
  152 + }
  153 + View view = ib.ivPic;
  154 + float[] size = CutUtil.measureBitmap(view, bitmap);
  155 +
  156 + ArrayList<Rect> rects = new ArrayList<>();
  157 + for (ImageBean.Cut cut: imageBean.getCuts()) {
  158 + if (cut.getRect1() == null) continue;
  159 + Rect rectV = cut.getRect1();
  160 + rects.add(getRectB(rectV, bitmap, size));
  161 + }
  162 + if (list.isEmpty()) {
  163 + showToast("请先框选题目");
  164 + return;
  165 + }
  166 +
  167 + Intent intent = new Intent(this, JudgeActivity.class);
  168 + intent.putExtra("path", imageBean.getPath());
  169 + intent.putParcelableArrayListExtra("rects", rects);
  170 +
  171 + startActivity(intent);
  172 + }
  173 +
  174 + private Rect getRectB(Rect rectV, Bitmap bitmap, float[] measuredSize) {
  175 + float realW = measuredSize[0];
  176 + float realH = measuredSize[1];
  177 + float offsetX = measuredSize[2];
  178 + float offsetY = measuredSize[3];
  179 + float percentX = bitmap.getWidth() / realW;
  180 + float percentY = bitmap.getHeight() / realH;
  181 +
  182 + float left = (rectV.left - offsetX) * percentX;
  183 + float right = (rectV.right - offsetX) * percentX;
  184 + float top = (rectV.top - offsetY) * percentY;
  185 + float bottom = (rectV.bottom - offsetY) * percentY;
  186 + Rect rectB = new Rect((int) left, (int) top, (int) right, (int) bottom);
  187 + return rectB;
119 188 }
120 189  
121 190 public void clearText() {
... ... @@ -128,8 +197,8 @@ public class ImageActivity extends BaseRxActivity&lt;ActivityImageBinding&gt; implemen
128 197 }
129 198 });
130 199 Log.i("clearText", list.get(index).getPath());
131   - String base64 = BitmapUtils.imageToBase64(list.get(index).getPath());
132   - NetWorks.removeWriting(base64, new Observer<JsonObject>() {
  200 + String base64 = BitmapUtils.imageToBase64(list.get(index).getPath(), false);
  201 + NetWorks.baiduEnhance(base64, new Observer<JsonObject>() {
133 202 @Override
134 203 public void onSubscribe(Disposable d) {
135 204  
... ... @@ -170,7 +239,7 @@ public class ImageActivity extends BaseRxActivity&lt;ActivityImageBinding&gt; implemen
170 239 }
171 240  
172 241 public void cut(String path) {
173   - String base64 = BitmapUtils.imageToBase64(path);
  242 + String base64 = BitmapUtils.imageToBase64WithUrlEncode(path);
174 243 Log.i("figLoaction", path);
175 244 NetWorks.cut(base64, new Observer<CutPicBean>() {
176 245 @Override
... ...
app/src/main/java/com/hjx/parent/JudgeActivity.java
... ... @@ -0,0 +1,173 @@
  1 +package com.hjx.parent;
  2 +
  3 +import android.annotation.SuppressLint;
  4 +import android.graphics.Bitmap;
  5 +import android.graphics.Rect;
  6 +import android.os.Bundle;
  7 +import android.util.Log;
  8 +
  9 +import com.bumptech.glide.Glide;
  10 +import com.hjx.parent.api.JudgeRepository;
  11 +import com.hjx.parent.databinding.ActivityJudgeBinding;
  12 +import com.hjx.parent.databinding.LayoutJudgeRectBinding;
  13 +import com.hjx.parent.rx.BaseRxActivity;
  14 +import com.hjx.parent.utils.CutUtil;
  15 +
  16 +import java.io.File;
  17 +import java.util.ArrayList;
  18 +import java.util.List;
  19 +
  20 +import io.reactivex.Observable;
  21 +import io.reactivex.Single;
  22 +import top.zibin.luban.Luban;
  23 +
  24 +public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> {
  25 +
  26 + private Bitmap bitmap;
  27 +
  28 + private final List<JudgeCut> mList = new ArrayList<>();
  29 +
  30 + @SuppressLint("CheckResult")
  31 + @Override
  32 + public void initView(Bundle savedInstanceState) {
  33 + binding.ivBack.setOnClickListener(v -> {
  34 + onBackPressed();
  35 + });
  36 + String path = getIntent().getStringExtra("path");
  37 + if (path == null) return;
  38 + final ArrayList<Rect> rects = getIntent().getParcelableArrayListExtra("rects");
  39 + if (rects == null) return;
  40 +
  41 + Single.just(path)
  42 + .map(origin -> Luban.with(this).load(origin).ignoreBy(300).get().get(0))
  43 + .map(file -> Glide.with(this).asBitmap().load(file).submit().get())
  44 + .compose(transformSingle())
  45 + .subscribe((bitmap, th) -> {
  46 + if (th != null) th.printStackTrace();
  47 + if (bitmap == null) return;
  48 + this.bitmap = bitmap;
  49 +
  50 + binding.ivPic.setImageBitmap(bitmap);
  51 + CutUtil.onLayoutReady(binding.ivPic, v -> {
  52 + prepareRects(rects);
  53 + });
  54 + });
  55 + binding.btnSelectAll.setOnClickListener(v -> {
  56 + if (mList.isEmpty()) return;
  57 + mList.forEach(it -> it.vb.getRoot().setSelected(true));
  58 + checkCount();
  59 + });
  60 + }
  61 +
  62 + private void prepareRects(List<Rect> rects) {
  63 + mList.clear();
  64 + binding.flRects.removeAllViews();
  65 + float[] measuredSize = CutUtil.measureBitmap(binding.ivPic, bitmap);
  66 + for (int i = 0; i < rects.size(); i++) {
  67 + Rect it = rects.get(i);
  68 + Bitmap bitmap = CutUtil.cut(this.bitmap, it.left, it.top, it.width(), it.height(), this);
  69 + Rect rect = measureRect(it, measuredSize);
  70 + LayoutJudgeRectBinding vb = showRect(rect);
  71 + mList.add(new JudgeCut(i, bitmap, rect, vb));
  72 + }
  73 +
  74 + judge();
  75 + }
  76 +
  77 + @SuppressLint("CheckResult")
  78 + private void judge() {
  79 + showLoadingDialog("");
  80 + Observable.fromIterable(mList)
  81 + .map(it -> {
  82 + if (it.url != null && !it.url.isEmpty()) return it;
  83 + String base64 = CutUtil.bitmapToBase64(it.bitmap, true);
  84 + it.url = base64;
  85 + return it;
  86 + })
  87 + .flatMap(it -> JudgeRepository.singleJudge(it.url)
  88 + .map(result -> {
  89 + it.correctResult = result;
  90 + return it;
  91 + })
  92 + .toObservable()
  93 + )
  94 + .compose(transform())
  95 + .subscribe(it -> {
  96 + if (it.correctResult == 1) {
  97 + it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct);
  98 + } else if (it.correctResult == 2) {
  99 + it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong);
  100 + }
  101 + it.vb.getRoot().setSelected(it.correctResult != 1);
  102 + checkCount();
  103 + }, th -> {
  104 + cancelLoadingDialog();
  105 + Log.e(getClass().getName(), "", th);
  106 + }, this::cancelLoadingDialog)
  107 + ;
  108 + }
  109 +
  110 + private LayoutJudgeRectBinding showRect(Rect rect) {
  111 + LayoutJudgeRectBinding vb = LayoutJudgeRectBinding.inflate(getLayoutInflater(), binding.flRects, false);
  112 +
  113 + vb.getRoot().setMinimumWidth(rect.width());
  114 + vb.getRoot().setMinimumHeight(rect.height());
  115 + vb.getRoot().setTranslationX((float) rect.left);
  116 + vb.getRoot().setTranslationY((float) rect.top);
  117 + vb.getRoot().setOnClickListener(v -> {
  118 + v.setSelected(!v.isSelected());
  119 + checkCount();
  120 + });
  121 + binding.flRects.addView(vb.getRoot());
  122 +
  123 + return vb;
  124 + }
  125 +
  126 + @SuppressLint("SetTextI18n")
  127 + private void checkCount() {
  128 + int count = (int) mList.stream().filter(it -> it.vb.getRoot().isSelected()).count();
  129 + if (count == 0) binding.btnAdd.setText("加入错题");
  130 + else binding.btnAdd.setText("加入错题(" + count + ")");
  131 + binding.btnAdd.setEnabled(count > 0);
  132 + }
  133 +
  134 + /** bitmapRect 转换为 viewRect */
  135 + private Rect measureRect(Rect rect, float[] measuredSize) {
  136 + float realW = measuredSize[0];
  137 + float realH = measuredSize[1];
  138 + float offsetX = measuredSize[2];
  139 + float offsetY = measuredSize[3];
  140 + float percentX = realW / bitmap.getWidth();
  141 + float percentY = realH / bitmap.getHeight();
  142 +
  143 + float left = rect.left * percentX + offsetX;
  144 + float right = rect.right * percentX + offsetX;
  145 + float top = rect.top * percentY + offsetY;
  146 + float bottom = rect.bottom * percentY + offsetY;
  147 + return new Rect((int) left, (int) top, (int) right, (int) bottom);
  148 + }
  149 +
  150 + @Override
  151 + protected ActivityJudgeBinding getViewBinding() {
  152 + return ActivityJudgeBinding.inflate(getLayoutInflater());
  153 + }
  154 +
  155 + static class JudgeCut {
  156 + final int index;
  157 + final Bitmap bitmap;
  158 + final Rect rect;
  159 + final LayoutJudgeRectBinding vb;
  160 +
  161 + String url;
  162 +
  163 + /** 0:未批改;1:正确;2:错误;3:未作答 */
  164 + int correctResult = 0;
  165 +
  166 + public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) {
  167 + this.index = index;
  168 + this.bitmap = bitmap;
  169 + this.rect = rect;
  170 + this.vb = vb;
  171 + }
  172 + }
  173 +}
... ...
app/src/main/java/com/hjx/parent/adapter/ImageAdapter.java
... ... @@ -7,6 +7,7 @@ import android.graphics.BitmapFactory;
7 7 import android.graphics.Rect;
8 8 import android.graphics.RectF;
9 9 import android.util.Log;
  10 +import android.util.SparseArray;
10 11 import android.view.LayoutInflater;
11 12 import android.view.View;
12 13 import android.view.ViewGroup;
... ... @@ -27,9 +28,12 @@ import com.prws.common.utils.CommonUtil;
27 28 import java.util.List;
28 29  
29 30 public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageHolder> {
  31 + public SparseArray<ItemImageBinding> viewArray = new SparseArray<>();
  32 +
30 33 private List<ImageBean> list;
31 34 private ImageActivity context;
32 35  
  36 +
33 37 public ImageAdapter(ImageActivity context, List<ImageBean> list) {
34 38 this.context = context;
35 39 this.list = list;
... ... @@ -44,6 +48,8 @@ public class ImageAdapter extends RecyclerView.Adapter&lt;ImageAdapter.ImageHolder&gt;
44 48  
45 49 @Override
46 50 public void onBindViewHolder(@NonNull ImageHolder holder, int position) {
  51 + viewArray.put(position, holder.binding);
  52 +
47 53 ImageBean imageBean = list.get(position);
48 54 Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath());
49 55 float imageHeight = bitmap.getHeight();
... ...
app/src/main/java/com/hjx/parent/api/ChatApi.java
... ... @@ -0,0 +1,17 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +import io.reactivex.Single;
  4 +import retrofit2.http.Body;
  5 +import retrofit2.http.Header;
  6 +import retrofit2.http.POST;
  7 +import retrofit2.http.Url;
  8 +
  9 +public interface ChatApi {
  10 + @POST
  11 + Single<ChatResponse> aiChat(
  12 + @Url String url,
  13 + @Header("Authorization") String token,
  14 + @Body ChatRequest body
  15 + );
  16 +
  17 +}
... ...
app/src/main/java/com/hjx/parent/api/ChatChoices.java
... ... @@ -0,0 +1,13 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +import com.google.gson.annotations.SerializedName;
  4 +
  5 +public class ChatChoices {
  6 +
  7 + public ChatMessage message;
  8 + public int index;
  9 + @SerializedName("finish_reason")
  10 + public String finishReason;
  11 + public String logprobs;
  12 +
  13 +}
... ...
app/src/main/java/com/hjx/parent/api/ChatError.java
... ... @@ -0,0 +1,8 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +public class ChatError {
  4 + String code;
  5 + String message;
  6 + String param;
  7 + String type;
  8 +}
... ...
app/src/main/java/com/hjx/parent/api/ChatMessage.java
... ... @@ -0,0 +1,45 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +import java.util.Objects;
  6 +
  7 +public class ChatMessage {
  8 + public ChatMessage() {
  9 + }
  10 + public ChatMessage(String role, Object content) {
  11 + this.role = role;
  12 + this.content = content;
  13 + }
  14 +
  15 + public String role;
  16 + public Object content;
  17 +
  18 + public static ChatMessage fromImage(String role, String text, String... urls) {
  19 + List<ContentItem> items = new ArrayList<>();
  20 + if (text != null && !text.isEmpty()) {
  21 + items.add(new ContentItem(ContentItem.TYPE_TEXT, text));
  22 + }
  23 + for (String it: urls) {
  24 + ContentItem.ContentImage image = new ContentItem.ContentImage(it);
  25 + items.add(new ContentItem(ContentItem.TYPE_IMAGE, image));
  26 + }
  27 + return new ChatMessage(role, items);
  28 + }
  29 +
  30 + public String getTextContent() {
  31 + if (content == null) return null;
  32 + if (content instanceof String) return (String) content;
  33 + ContentItem item = firstText();
  34 + return item == null ? null : item.text;
  35 + }
  36 +
  37 + private ContentItem firstText() {
  38 + if (!(content instanceof List<?>)) return null;
  39 + List<?> anyList = (List<?>) content;
  40 + return anyList.stream()
  41 + .map(ContentItem::reSerialize)
  42 + .filter(Objects::nonNull)
  43 + .findFirst().orElse(null);
  44 + }
  45 +}
... ...
app/src/main/java/com/hjx/parent/api/ChatRequest.java
... ... @@ -0,0 +1,15 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +import java.util.List;
  4 +
  5 +public class ChatRequest {
  6 + public String model;
  7 + public List<ChatMessage> messages;
  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 + }
  15 +}
... ...
app/src/main/java/com/hjx/parent/api/ChatResponse.java
... ... @@ -0,0 +1,19 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +import com.google.gson.annotations.SerializedName;
  4 +
  5 +import java.util.List;
  6 +
  7 +public class ChatResponse {
  8 + public List<ChatChoices> choices;
  9 + public String created;
  10 + public String id;
  11 + public String model;
  12 + @SerializedName("service_tier")
  13 + public String serviceTier;
  14 + @SerializedName("object")
  15 + public String obj;
  16 + public ChatUsage usage;
  17 +
  18 + public ChatError error;
  19 +}
... ...
app/src/main/java/com/hjx/parent/api/ChatUsage.java
... ... @@ -0,0 +1,16 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +import com.google.gson.annotations.SerializedName;
  4 +
  5 +public class ChatUsage {
  6 + @SerializedName("completion_tokens")
  7 + public int completionTokens;
  8 + @SerializedName("prompt_tokens")
  9 + public int promptTokens;
  10 + @SerializedName("total_tokens")
  11 + public int totalTokens;
  12 + @SerializedName("prompt_tokens_details")
  13 + public PromptTokensDetails promptTokensDetails;
  14 + @SerializedName("completion_tokens_details")
  15 + public CompletionTokensDetails completionTokensDetails;
  16 +}
... ...
app/src/main/java/com/hjx/parent/api/CompletionTokensDetails.java
... ... @@ -0,0 +1,5 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +public class CompletionTokensDetails {
  4 + public int reasoningTokens;
  5 +}
... ...
app/src/main/java/com/hjx/parent/api/ContentItem.java
... ... @@ -0,0 +1,48 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +import com.google.gson.Gson;
  4 +import com.google.gson.annotations.SerializedName;
  5 +
  6 +public class ContentItem {
  7 + public static final String TYPE_TEXT = "text";
  8 + public static final String TYPE_IMAGE = "image_url";
  9 +
  10 +
  11 + public ContentItem() {
  12 + }
  13 + public ContentItem(String type, String text) {
  14 + this.type = type;
  15 + this.text = text;
  16 + }
  17 + public ContentItem(String type, ContentImage imageUrl) {
  18 + this.type = type;
  19 + this.imageUrl = imageUrl;
  20 + }
  21 +
  22 + public String type;
  23 + public String text;
  24 + @SerializedName("image_url")
  25 + public ContentImage imageUrl;
  26 +
  27 + public static class ContentImage {
  28 + public ContentImage(String url) {
  29 + this.url = url;
  30 + }
  31 +
  32 + public String url;
  33 + }
  34 +
  35 +
  36 + private static final Gson gson = new Gson();
  37 + static ContentItem reSerialize(Object any) {
  38 + if (any == null) return null;
  39 + try {
  40 + String json = gson.toJson(any);
  41 + ContentItem it = gson.fromJson(json, ContentItem.class);
  42 + return it;
  43 + } catch (Throwable t) {
  44 + t.printStackTrace();
  45 + }
  46 + return null;
  47 + }
  48 +}
... ...
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/api/PromptTokensDetails.java
... ... @@ -0,0 +1,5 @@
  1 +package com.hjx.parent.api;
  2 +
  3 +public class PromptTokensDetails {
  4 + public int cachedTokens;
  5 +}
... ...
app/src/main/java/com/hjx/parent/utils/CutUtil.java
... ... @@ -0,0 +1,102 @@
  1 +package com.hjx.parent.utils;
  2 +
  3 +import android.content.Context;
  4 +import android.graphics.Bitmap;
  5 +import android.graphics.Canvas;
  6 +import android.graphics.Color;
  7 +import android.graphics.Paint;
  8 +import android.util.Base64;
  9 +import android.view.View;
  10 +import android.view.ViewTreeObserver;
  11 +
  12 +import com.bumptech.glide.Glide;
  13 +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
  14 +import com.hjx.parent.function.Function1;
  15 +
  16 +import java.io.ByteArrayOutputStream;
  17 +import java.io.File;
  18 +import java.io.IOException;
  19 +import java.util.List;
  20 +
  21 +import top.zibin.luban.Luban;
  22 +
  23 +public class CutUtil {
  24 +
  25 + public static float[] measureBitmap(View view, Bitmap bitmap) {
  26 + float realW;
  27 + float realH;
  28 + float offsetX;
  29 + float offsetY;
  30 +
  31 + float vp = 1f * view.getWidth() / view.getHeight();
  32 + float bp = 1f * bitmap.getWidth() / bitmap.getHeight();
  33 +
  34 + if (vp > bp) {
  35 + realW = view.getHeight() * bp;
  36 + realH = (float) view.getHeight();
  37 + offsetY = 0f;
  38 + offsetX = (view.getWidth() - realW) * 0.5f;
  39 + } else if (vp < bp) {
  40 + realW = (float) view.getWidth();
  41 + realH = view.getWidth() * (1f / bp);
  42 + offsetX = 0f;
  43 + offsetY = (view.getHeight() - realH) * 0.5f;
  44 + } else {
  45 + realW = (float) view.getWidth();
  46 + realH = (float) view.getHeight();
  47 + offsetX = 0f;
  48 + offsetY = 0f;
  49 + }
  50 +
  51 + return new float[]{realW, realH, offsetX, offsetY};
  52 + }
  53 +
  54 + public static Bitmap cut(Bitmap source, float x, float y, int w, int h, Context context) {
  55 + // 获取 Glide 的 BitmapPool
  56 + BitmapPool bitmapPool = Glide.get(context).getBitmapPool();
  57 +
  58 + // 从 BitmapPool 中获取可复用的 Bitmap
  59 + Bitmap result = bitmapPool.get(w, h, source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888);
  60 +
  61 + // 填充白色背景
  62 + result.eraseColor(Color.WHITE);
  63 +
  64 + // 创建画布并绘制
  65 + Canvas canvas = new Canvas(result);
  66 + Paint paint = new Paint();
  67 + canvas.drawBitmap(source, -x, -y, paint);
  68 +
  69 + return result;
  70 + }
  71 +
  72 + public static void onLayoutReady(final View view, final Function1<View> action) {
  73 + view.getViewTreeObserver().addOnGlobalLayoutListener(
  74 + new ViewTreeObserver.OnGlobalLayoutListener() {
  75 + @Override
  76 + public void onGlobalLayout() {
  77 + view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
  78 + action.invoke(view);
  79 + }
  80 + }
  81 + );
  82 + }
  83 +
  84 + public static byte[] bitmapToByteArray(Bitmap bitmap) {
  85 + ByteArrayOutputStream output = new ByteArrayOutputStream();
  86 + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
  87 + return output.toByteArray();
  88 + }
  89 +
  90 + public static String bitmapToBase64(Bitmap bitmap, Boolean usePrefix) {
  91 + String base64 = Base64.encodeToString(bitmapToByteArray(bitmap), Base64.NO_WRAP);
  92 + if (usePrefix) return "data:image/jpeg;base64," + base64;
  93 + else return base64;
  94 + }
  95 +
  96 + public static List<File> compressAllSync(Context context, List<String> originList, int ignore) throws IOException {
  97 + return Luban.with(context).ignoreBy(ignore)
  98 + .setTargetDir(context.getExternalCacheDir().getAbsolutePath())
  99 + .load(originList)
  100 + .get();
  101 + }
  102 +}
... ...
app/src/main/res/drawable/bg_judge_cut.xml
... ... @@ -0,0 +1,15 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<selector xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <item android:state_selected="true">
  4 + <shape>
  5 + <solid android:color="#1A1C90F3"/>
  6 + <stroke android:color="#1C90F3" android:width="1px"/>
  7 + </shape>
  8 + </item>
  9 + <item>
  10 + <shape>
  11 + <solid android:color="#33000000"/>
  12 + <stroke android:color="#666666" android:width="1px"/>
  13 + </shape>
  14 + </item>
  15 +</selector>
0 16 \ No newline at end of file
... ...
app/src/main/res/drawable/check_circle_12.xml
... ... @@ -0,0 +1,15 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <item android:width="12dp" android:height="12dp">
  4 + <selector>
  5 + <item android:state_checked="true"
  6 + android:drawable="@drawable/png_ic_check_circle"/>
  7 + <item>
  8 + <shape>
  9 + <corners android:radius="20dp"/>
  10 + <stroke android:width="1.5dp" android:color="#333"/>
  11 + </shape>
  12 + </item>
  13 + </selector>
  14 + </item>
  15 +</layer-list>
0 16 \ No newline at end of file
... ...
app/src/main/res/drawable/ic_add.png

1.12 KB

app/src/main/res/drawable/ic_judge_rect_select.xml
... ... @@ -0,0 +1,5 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<selector xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <item android:drawable="@drawable/png_rect_selected" android:state_selected="true"/>
  4 + <item android:drawable="@drawable/png_rect_add"/>
  5 +</selector>
0 6 \ No newline at end of file
... ...
app/src/main/res/drawable/ic_rect_20.xml
... ... @@ -0,0 +1,5 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <item android:drawable="@drawable/png_ic_rect"
  4 + android:width="20dp" android:height="20dp"/>
  5 +</layer-list>
0 6 \ No newline at end of file
... ...
app/src/main/res/drawable/png_ic_check_circle.png

1.05 KB

app/src/main/res/drawable/png_ic_judge_correct.png

1.09 KB

app/src/main/res/drawable/png_ic_judge_wrong.png

1.12 KB

app/src/main/res/drawable/png_ic_rect.png

1.72 KB

app/src/main/res/drawable/png_rect_add.png

1.12 KB

app/src/main/res/drawable/png_rect_selected.png

902 Bytes

app/src/main/res/layout/activity_image.xml
1 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2 + xmlns:tools="http://schemas.android.com/tools"
2 3 android:layout_width="match_parent"
3 4 android:layout_height="match_parent"
4   - android:orientation="vertical">
  5 + xmlns:app="http://schemas.android.com/apk/res-auto"
  6 + android:orientation="vertical"
  7 + tools:ignore="HardcodedText">
5 8  
6 9 <RelativeLayout
7 10 android:layout_width="match_parent"
... ... @@ -102,8 +105,10 @@
102 105 android:src="@mipmap/ic_next_gray" />
103 106 </RelativeLayout>
104 107  
105   - <RelativeLayout
  108 + <LinearLayout
106 109 android:id="@+id/rl_bottom"
  110 + android:orientation="horizontal"
  111 + android:gravity="center_vertical"
107 112 android:layout_width="match_parent"
108 113 android:layout_height="70dp"
109 114 android:layout_alignParentBottom="true"
... ... @@ -113,13 +118,12 @@
113 118 android:id="@+id/ll_edit"
114 119 android:layout_width="wrap_content"
115 120 android:layout_height="wrap_content"
116   - android:layout_centerVertical="true"
117   - android:layout_marginLeft="15dp"
  121 + android:layout_marginStart="15dp"
118 122 android:orientation="vertical">
119 123  
120 124 <ImageView
121   - android:layout_width="25dp"
122   - android:layout_height="25dp"
  125 + android:layout_width="20dp"
  126 + android:layout_height="20dp"
123 127 android:layout_gravity="center_horizontal"
124 128 android:src="@mipmap/ic_pic_edit" />
125 129  
... ... @@ -128,35 +132,45 @@
128 132 android:layout_height="wrap_content"
129 133 android:layout_marginTop="5dp"
130 134 android:text="图片编辑"
  135 + android:textColor="#333"
131 136 android:textSize="11sp" />
132 137 </LinearLayout>
133 138  
134   - <TextView
  139 + <androidx.appcompat.widget.AppCompatTextView
135 140 android:id="@+id/tv_add"
136   - android:layout_width="140dp"
137   - android:layout_height="40dp"
138   - android:layout_centerVertical="true"
139   - android:layout_marginRight="15dp"
140   - android:layout_toLeftOf="@+id/tv_save"
  141 + android:text="手动框选"
  142 + android:textSize="11sp"
  143 + android:textColor="#333"
  144 + android:gravity="center_horizontal"
  145 + android:drawableTop="@drawable/ic_rect_20"
  146 + android:drawablePadding="5dp"
  147 + android:layout_marginStart="12dp"
  148 + android:layout_width="wrap_content"
  149 + android:layout_height="wrap_content" />
  150 +
  151 + <Space style="@style/empty_space"/>
  152 +
  153 + <TextView
  154 + android:id="@+id/btnJudge"
  155 + android:layout_width="112dp"
  156 + android:layout_height="36dp"
141 157 android:background="@drawable/bg_soild_orange_5"
142 158 android:gravity="center"
143   - android:text="手动框选"
  159 + android:text="去批改"
144 160 android:textColor="@color/white"
145   - android:textSize="18sp" />
  161 + android:textSize="16sp" />
146 162  
147 163 <TextView
148 164 android:id="@+id/tv_save"
149   - android:layout_width="140dp"
150   - android:layout_height="40dp"
151   - android:layout_alignParentRight="true"
152   - android:layout_centerVertical="true"
153   - android:layout_marginRight="15dp"
  165 + android:layout_width="112dp"
  166 + android:layout_height="36dp"
  167 + android:layout_marginHorizontal="15dp"
154 168 android:background="@drawable/bg_soild_blue_light_5"
155 169 android:enabled="false"
156 170 android:gravity="center"
157 171 android:text="保存错题"
158 172 android:textColor="@color/white"
159   - android:textSize="18sp" />
160   - </RelativeLayout>
  173 + android:textSize="16sp" />
  174 + </LinearLayout>
161 175 </RelativeLayout>
162 176 </LinearLayout>
163 177 \ No newline at end of file
... ...
app/src/main/res/layout/activity_judge.xml
... ... @@ -0,0 +1,73 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:app="http://schemas.android.com/apk/res-auto"
  4 + xmlns:tools="http://schemas.android.com/tools"
  5 + android:orientation="vertical"
  6 + android:layout_width="match_parent"
  7 + android:layout_height="match_parent"
  8 + tools:ignore="UseCompoundDrawables,HardcodedText,SmallSp,ContentDescription">
  9 +
  10 + <androidx.appcompat.widget.Toolbar
  11 + android:background="@color/white"
  12 + app:contentInsetStart="0dp"
  13 + android:layout_width="match_parent"
  14 + android:layout_height="40dp">
  15 + <ImageView
  16 + android:id="@+id/ivBack"
  17 + android:layout_width="30dp"
  18 + android:layout_height="36dp"
  19 + android:layout_centerVertical="true"
  20 + android:layout_marginStart="5dp"
  21 + android:padding="10dp"
  22 + android:src="@mipmap/icon_back" />
  23 + </androidx.appcompat.widget.Toolbar>
  24 +
  25 + <FrameLayout
  26 + android:background="@color/white"
  27 + android:padding="8dp"
  28 + android:layout_margin="16dp"
  29 + android:layout_width="match_parent"
  30 + android:layout_height="0px"
  31 + android:layout_weight="1">
  32 + <ImageView
  33 + android:id="@+id/ivPic"
  34 + android:layout_width="match_parent"
  35 + android:layout_height="match_parent"/>
  36 + <FrameLayout
  37 + android:id="@+id/flRects"
  38 + android:layout_width="match_parent"
  39 + android:layout_height="match_parent" />
  40 + </FrameLayout>
  41 +
  42 + <LinearLayout
  43 + android:orientation="horizontal"
  44 + android:gravity="center_vertical"
  45 + android:paddingHorizontal="16dp"
  46 + android:background="@color/white"
  47 + android:layout_width="match_parent"
  48 + android:layout_height="64dp">
  49 + <androidx.appcompat.widget.AppCompatTextView
  50 + android:id="@+id/btnSelectAll"
  51 + android:text="全选"
  52 + android:textSize="16sp"
  53 + android:textColor="#333"
  54 + android:gravity="center_vertical"
  55 + android:paddingHorizontal="8dp"
  56 + android:paddingVertical="4dp"
  57 + android:layout_width="wrap_content"
  58 + android:layout_height="wrap_content"/>
  59 +
  60 + <Space style="@style/empty_space"/>
  61 + <TextView
  62 + android:id="@+id/btnAdd"
  63 + android:text="加入错题"
  64 + android:textSize="16sp"
  65 + android:textColor="@color/white"
  66 + android:gravity="center"
  67 + android:background="@drawable/shape_radius_5"
  68 + android:backgroundTint="#1C90F3"
  69 + android:layout_width="112dp"
  70 + android:layout_height="36dp"/>
  71 + </LinearLayout>
  72 +
  73 +</LinearLayout>
0 74 \ No newline at end of file
... ...
app/src/main/res/layout/layout_judge_rect.xml
... ... @@ -0,0 +1,27 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:app="http://schemas.android.com/apk/res-auto"
  4 + xmlns:tools="http://schemas.android.com/tools"
  5 + android:orientation="vertical"
  6 + android:background="@drawable/bg_judge_cut"
  7 + android:minWidth="160dp"
  8 + android:minHeight="48dp"
  9 + android:layout_width="wrap_content"
  10 + android:layout_height="wrap_content"
  11 + tools:ignore="UseCompoundDrawables,HardcodedText,SmallSp,ContentDescription">
  12 +
  13 + <ImageView
  14 + android:id="@+id/ivResult"
  15 + tools:src="@drawable/png_ic_judge_correct"
  16 + android:layout_gravity="end"
  17 + android:layout_margin="8dp"
  18 + android:layout_width="12dp"
  19 + android:layout_height="12dp"/>
  20 +
  21 + <ImageView
  22 + android:src="@drawable/ic_judge_rect_select"
  23 + android:layout_gravity="center"
  24 + android:layout_width="12dp"
  25 + android:layout_height="12dp"/>
  26 +
  27 +</FrameLayout>
0 28 \ No newline at end of file
... ...
libs/common/build.gradle
... ... @@ -18,23 +18,21 @@ android {
18 18  
19 19 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
20 20  
21   - buildConfigField("String", "APIKey1", "\"eCa3YzEjTBBiNjlXcNnjnldP\"")
22   - buildConfigField("String", "SecretKey1", "\"KnZPmjF0ZzmxWV964mzmm6yuDljnETLt\"")
  21 + buildConfigField("String", "APIKey", "\"oj9XT8AOeTeLkdqaEX7RJA0N\"")
  22 + buildConfigField("String", "SecretKey", "\"AfUFmACkfbd0RMuk11qbw1TW5LtxtJHK\"")
  23 + buildConfigField("String", "APIKey1", "\"oj9XT8AOeTeLkdqaEX7RJA0N\"")
  24 + buildConfigField("String", "SecretKey1", "\"AfUFmACkfbd0RMuk11qbw1TW5LtxtJHK\"")
23 25 }
24 26  
25 27 buildTypes {
26 28 debug {
27 29 minifyEnabled false
28 30 buildConfigField("String", "SERVER_URL", "\"${url.server_url}\"")
29   - buildConfigField("String", "APIKey", "\"OmmSqorNFXjVHXlZWhHAyGyQ\"")
30   - buildConfigField("String", "SecretKey", "\"Uwjz4XGi89RN4Mvl5mievKpjqpGgUy6D\"")
31 31 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
32 32 }
33 33 release {
34 34 minifyEnabled false
35 35 buildConfigField("String", "SERVER_URL", "\"${url.server_url_online}\"")
36   - buildConfigField("String", "APIKey", "\"OmmSqorNFXjVHXlZWhHAyGyQ\"")
37   - buildConfigField("String", "SecretKey", "\"Uwjz4XGi89RN4Mvl5mievKpjqpGgUy6D\"")
38 36 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
39 37 }
40 38 }
... ...
libs/common/src/main/java/com/prws/common/net/NetWorks.java
... ... @@ -24,6 +24,7 @@ import com.prws.common.utils.SharedPreferencesUtil;
24 24  
25 25 import java.io.File;
26 26 import java.util.HashMap;
  27 +import java.util.LinkedHashMap;
27 28 import java.util.List;
28 29 import java.util.Map;
29 30  
... ... @@ -38,6 +39,7 @@ import okhttp3.RequestBody;
38 39 import okhttp3.ResponseBody;
39 40 import retrofit2.Call;
40 41 import retrofit2.Callback;
  42 +import retrofit2.Retrofit;
41 43 import retrofit2.http.Body;
42 44 import retrofit2.http.GET;
43 45 import retrofit2.http.Header;
... ... @@ -58,7 +60,8 @@ import retrofit2.http.Url;
58 60 */
59 61 public class NetWorks extends RetrofitUtils {
60 62 //服务器路径
61   - public static final NetService service_url = getMachineRetrofit(BuildConfig.SERVER_URL).create(NetService.class);
  63 + public static final Retrofit retrofit = getMachineRetrofit(BuildConfig.SERVER_URL);
  64 + public static final NetService service_url = retrofit.create(NetService.class);
62 65  
63 66 //设缓存有效期为1天
64 67 protected static final long CACHE_STALE_SEC = 60 * 60 * 24 * 1;
... ... @@ -152,6 +155,12 @@ public class NetWorks extends RetrofitUtils {
152 155 @POST
153 156 Observable<JsonObject> removeWriting(@Url String url, @Body RequestBody body);
154 157  
  158 + @POST("https://aip.baidubce.com/rest/2.0/ocr/v1/doc_crop_enhance")
  159 + Observable<JsonObject> baiduEnhance(
  160 + @Query("access_token") String token,
  161 + @Body Object any
  162 + );
  163 +
155 164 @POST
156 165 Observable<CutPicBean> cut(@Url String url, @Body RequestBody body);
157 166  
... ... @@ -336,6 +345,14 @@ public class NetWorks extends RetrofitUtils {
336 345 setSubscribe(service_url.removeWriting(("https://aip.baidubce.com/rest/2.0/ocr/v1/remove_handwriting?access_token=" + getBaiduToken()), body), observer);
337 346 }
338 347  
  348 + public static void baiduEnhance(String base64, Observer<JsonObject> observer) {
  349 + Map<String, Object> body = new LinkedHashMap<>();
  350 + body.put("image", base64);
  351 + body.put("scan_type", 3);
  352 + body.put("enhance_type", 3);
  353 + setSubscribe(service_url.baiduEnhance(getBaiduToken(), body), observer);
  354 + }
  355 +
339 356 public static void searchTeacher(String phone, Observer<ResponseResult<Teacher>> observer) {
340 357 setSubscribe(service_url.searchTeacher(getHeader(), phone), observer);
341 358 }
... ...
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 }
... ...
libs/common/src/main/java/com/prws/common/utils/BitmapUtils.java
... ... @@ -166,7 +166,12 @@ public class BitmapUtils {
166 166 /**
167 167 * 将图片转换成Base64编码的字符串
168 168 */
169   - public static String imageToBase64(String path) {
  169 + public static String imageToBase64WithUrlEncode(String path) {
  170 + return imageToBase64(path, true);
  171 + }
  172 +
  173 + public static String imageToBase64(String path, boolean urlEncode) {
  174 +
170 175 if (TextUtils.isEmpty(path)) {
171 176 return null;
172 177 }
... ... @@ -193,7 +198,8 @@ public class BitmapUtils {
193 198 }
194 199  
195 200 }
196   - return toURLEncoded(result);
  201 + if (urlEncode) return toURLEncoded(result);
  202 + else return result;
197 203 }
198 204  
199 205  
... ...