package com.hjx.parent; import android.annotation.SuppressLint; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Bundle; import android.util.Log; import com.bumptech.glide.Glide; import com.hjx.parent.api.JudgeRepository; import com.hjx.parent.databinding.ActivityJudgeBinding; import com.hjx.parent.databinding.LayoutJudgeRectBinding; import com.hjx.parent.dialog.ErrorInputDialog; import com.hjx.parent.rx.BaseRxActivity; import com.hjx.parent.utils.CutUtil; import com.prws.common.bean.TopicBean; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import io.reactivex.Observable; import io.reactivex.Single; import top.zibin.luban.Luban; public class JudgeActivity extends BaseRxActivity { private Bitmap bitmap; private final List mList = new ArrayList<>(); @SuppressLint("CheckResult") @Override public void initView(Bundle savedInstanceState) { binding.ivBack.setOnClickListener(v -> { onBackPressed(); }); String path = getIntent().getStringExtra("path"); if (path == null) return; final ArrayList rects = getIntent().getParcelableArrayListExtra("rects"); if (rects == null) return; Single.just(path) .map(File::new) .map(file -> Glide.with(this).asBitmap().load(file).submit().get()) .compose(transformSingle()) .subscribe((bitmap, th) -> { if (th != null) th.printStackTrace(); if (bitmap == null) return; this.bitmap = bitmap; binding.ivPic.setImageBitmap(bitmap); CutUtil.onLayoutReady(binding.ivPic, v -> { prepareRects(rects); }); }); binding.btnSelectAll.setOnClickListener(v -> { if (mList.isEmpty()) return; mList.forEach(it -> it.vb.getRoot().setSelected(true)); checkCount(); }); binding.btnSelectNone.setOnClickListener(v -> { if (mList.isEmpty()) return; mList.forEach(it -> it.vb.getRoot().setSelected(false)); checkCount(); }); binding.btnAdd.setOnClickListener(v -> { if (mList.isEmpty()) return; List selected = mList.stream() .filter(it -> it.vb.getRoot().isSelected()) .map(it -> { TopicBean bean = new TopicBean(); bean.setPath(it.getPath()); return bean; }) .collect(Collectors.toList()); ErrorInputDialog dialog = new ErrorInputDialog(this, selected); dialog.show(() -> { showToast("已加入错题本"); finish(); }); }); } private void prepareRects(List rects) { mList.clear(); binding.flRects.removeAllViews(); float[] measuredSize = CutUtil.measureBitmap(binding.ivPic, bitmap); for (int i = 0; i < rects.size(); i++) { Rect it = rects.get(i); Bitmap bitmap = CutUtil.cut(this.bitmap, it.left, it.top, it.width(), it.height(), this); Rect rect = measureRect(it, measuredSize); LayoutJudgeRectBinding vb = showRect(rect); mList.add(new JudgeCut(i, bitmap, rect, vb)); } judge(); } @SuppressLint("CheckResult") private void judge() { showLoadingDialog(""); Observable.fromIterable(mList) .map(it -> { if (it.url != null && !it.url.isEmpty()) return it; String base64 = CutUtil.bitmapToBase64(it.bitmap, true); it.url = base64; return it; }) .flatMap(it -> JudgeRepository.singleJudge(it.url) .map(result -> { it.correctResult = result; return it; }) .toObservable() ) .compose(transform()) .subscribe(it -> { if (it.correctResult == 1) { it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct); } else if (it.correctResult == 2) { it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong); } it.vb.getRoot().setSelected(it.correctResult != 1); checkCount(); }, th -> { cancelLoadingDialog(); Log.e(getClass().getName(), "", th); }, this::cancelLoadingDialog) ; } private LayoutJudgeRectBinding showRect(Rect rect) { LayoutJudgeRectBinding vb = LayoutJudgeRectBinding.inflate(getLayoutInflater(), binding.flRects, false); vb.getRoot().setMinimumWidth(rect.width()); vb.getRoot().setMinimumHeight(rect.height()); vb.getRoot().setTranslationX((float) rect.left); vb.getRoot().setTranslationY((float) rect.top); vb.getRoot().setOnClickListener(v -> { v.setSelected(!v.isSelected()); checkCount(); }); binding.flRects.addView(vb.getRoot()); return vb; } @SuppressLint("SetTextI18n") private void checkCount() { int count = (int) mList.stream().filter(it -> it.vb.getRoot().isSelected()).count(); if (count == 0) binding.btnAdd.setText("加入错题"); else binding.btnAdd.setText("加入错题(" + count + ")"); binding.btnAdd.setEnabled(count > 0); } /** bitmapRect 转换为 viewRect */ private Rect measureRect(Rect rect, float[] measuredSize) { float realW = measuredSize[0]; float realH = measuredSize[1]; float offsetX = measuredSize[2]; float offsetY = measuredSize[3]; float percentX = realW / bitmap.getWidth(); float percentY = realH / bitmap.getHeight(); float left = rect.left * percentX + offsetX; float right = rect.right * percentX + offsetX; float top = rect.top * percentY + offsetY; float bottom = rect.bottom * percentY + offsetY; return new Rect((int) left, (int) top, (int) right, (int) bottom); } @Override protected ActivityJudgeBinding getViewBinding() { return ActivityJudgeBinding.inflate(getLayoutInflater()); } static class JudgeCut { final int index; final Bitmap bitmap; final Rect rect; final LayoutJudgeRectBinding vb; String url; /** 0:未批改;1:正确;2:错误;3:未作答 */ int correctResult = 0; public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) { this.index = index; this.bitmap = bitmap; this.rect = rect; this.vb = vb; } private String path; public String getPath() { if (path != null) return path; path = CutUtil.saveBitmapToCache(bitmap, App.getInstance()); return path; } } }