詹子聪 5 rokov pred
rodič
commit
3fa496fffa

+ 1 - 1
app/src/main/AndroidManifest.xml

@@ -50,7 +50,7 @@
             android:screenOrientation="portrait" />
 
         <activity
-            android:name=".ui.camera.wechat.WechatCameraActivity"
+            android:name=".ui.camera.wechat.WechatOperationActivity"
             android:screenOrientation="portrait" />
 
         <activity

+ 2 - 2
app/src/main/java/com/miekir/ocr/PermissionActivity.java

@@ -10,7 +10,7 @@ import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
 import androidx.appcompat.app.AppCompatActivity;
 
-import com.miekir.ocr.ui.camera.wechat.WechatCameraActivity;
+import com.miekir.ocr.ui.camera.wechat.WechatOperationActivity;
 import com.tbruyelle.rxpermissions2.RxPermissions;
 
 
@@ -36,7 +36,7 @@ public class PermissionActivity extends AppCompatActivity {
                         //startActivity(new Intent(PermissionActivity.this, CropImageActivity.class));
 
 //                        startActivity(new Intent(PermissionActivity.this, OperationActivity.class));
-                        startActivity(new Intent(PermissionActivity.this, WechatCameraActivity.class));
+                        startActivity(new Intent(PermissionActivity.this, WechatOperationActivity.class));
                         finish();
                         //photoSelect();
                     } else {

+ 151 - 1
app/src/main/java/com/miekir/ocr/ui/OperationPresenter.java

@@ -326,11 +326,161 @@ public class OperationPresenter extends BasePresenter<IOperationView> {
         });
     }
 
+    public void startOcrFromBitmap(Context context, Bitmap originalBmp, int[] rectData, File file, String scene, boolean isScreenLandscape) {
+        getView().showLoading(context.getResources().getString(R.string.loading));
+        int mLeft = rectData[0];
+        int mTop = rectData[1];
+        int mRight = rectData[2];
+        int mBottom = rectData[3];
+        Observable.create(new ObservableOnSubscribe<String>() {
+            @Override
+            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
+                // 所以要先恢复原来的图片再裁剪
+                Bitmap normalBitmap = ImageUtil.rotateBitmap90(originalBmp);
+                int normalWidth = normalBitmap.getWidth();
+                int normalHeight = normalBitmap.getHeight();
+
+                // 图片不旋转,以屏幕为参考系进行缩小或者放大,直到图片一条边等于屏幕的一条边,图片的另一条边大于等于屏幕的另一条边
+                int realLeft;
+                int realTop;
+                int realWidth;
+                int realHeight;
+
+                //boolean isLandscape = mBottom-mTop > mRight-mLeft;
+
+                // 图片宽度与屏幕宽度的比
+                float widthD = 1.0f * normalWidth / SizeTool.SCREEN_WIDTH;
+                // 图片高度与屏幕高度的比
+                float heightD = 1.0f * normalHeight / mHeight;
+                boolean isPortraitPhoto = BigDecimal.valueOf(heightD).compareTo(BigDecimal.valueOf(widthD)) > 0;
+                if (isPortraitPhoto) {
+                    // 高的倍距大,以宽为基准
+                    if (widthD > 0) {
+                        // 图片宽要缩小到屏幕宽
+                        float pivot = 1.0f * normalWidth / SizeTool.SCREEN_WIDTH;
+                        realLeft = (int) (mLeft * pivot);
+                        realTop = (int) (mTop * pivot);
+                        realWidth = (int) ((mRight - mLeft) * pivot);
+                        realHeight = (int) ((mBottom - mTop) * pivot);
+                    } else {
+                        // 屏幕宽要缩小到图片宽
+                        float pivot = 1.0f * normalWidth / SizeTool.SCREEN_WIDTH;
+                        realLeft = (int) (mLeft * pivot);
+                        realTop = (int) (mTop * pivot);
+                        realWidth = (int) ((mRight - mLeft) * pivot);
+                        realHeight = (int) ((mBottom - mTop) * pivot);
+                    }
+                } else {
+                    // 宽的倍距大,以高为基准
+                    if (heightD > 0) {
+                        // 图片高要缩小到屏幕高
+                        float pivot = 1.0f * normalHeight / mHeight;
+                        realLeft = (int) (mLeft * pivot);
+                        realTop = (int) (mTop * pivot);
+                        realWidth = (int) ((mRight - mLeft) * pivot);
+                        realHeight = (int) ((mBottom - mTop) * pivot);
+                    } else {
+                        // 屏幕高要缩小到图片高,其实一样
+                        float pivot = 1.0f * normalHeight / mHeight;
+                        realLeft = (int) (mLeft * pivot);
+                        realTop = (int) (mTop * pivot);
+                        realWidth = (int) ((mRight - mLeft) * pivot);
+                        realHeight = (int) ((mBottom - mTop) * pivot);
+                    }
+                }
+
+
+                Bitmap croppedBmp = Bitmap.createBitmap(normalBitmap, realLeft, realTop, realWidth, realHeight);
+
+                // 旋转90度,让OCR可以识别
+                Bitmap rotatedBitmap;
+                //if (isLandscape) {
+                if (isScreenLandscape) {
+                    rotatedBitmap = ImageUtil.rotateBitmap(croppedBmp, -90);
+                } else {
+                    rotatedBitmap = croppedBmp;
+                }
+
+                if (!file.getParentFile().exists()) {
+                    file.getParentFile().mkdirs();
+                }
+                int max = rotatedBitmap.getWidth() > rotatedBitmap.getHeight() ? rotatedBitmap.getWidth() : rotatedBitmap.getHeight();
+                int multi = 1;
+                if (max > 1000) {
+                    multi = max / 1000 + 1;
+                }
+
+                // 压缩图片
+                boolean saveCropSuccess = ImageUtil.saveBitmapFile(rotatedBitmap, file, multi);
+
+                originalBmp.recycle();
+                croppedBmp.recycle();
+                rotatedBitmap.recycle();
+                if (saveCropSuccess) {
+                    File compressedFile = new Compressor(context.getApplicationContext())
+                            .setQuality(90)
+                            .setDestinationDirectoryPath(file.getParentFile().getAbsolutePath())
+                            .compressToFile(file, "cp_" + file.getName());
+
+                    file.delete();
+                    // 通知相册去获取
+                    MediaScannerConnection.scanFile(context, new String[] { compressedFile.getAbsolutePath() }, new String[] { "image/jpeg" }, null);
+                    // 保存最终截图成功
+                    // 根据URI获取图片的base64字符串
+                    String photoBase64 = Base64Tool.getBase64FromFilePath(compressedFile.getAbsolutePath());
+                    if (TextUtils.isEmpty(photoBase64)) {
+                        emitter.onError(new Exception("Empty image"));
+                    } else {
+                        emitter.onNext(photoBase64);
+                    }
+                } else {
+                    emitter.onError(new Exception("Empty image"));
+                }
+            }
+        })
+                /*.filter(base64String -> {
+                    // 图片base64不为空才继续,否则直接忽略,没有任何回调会被调用
+                    return !TextUtils.isEmpty(base64String);
+                })*/
+                .flatMap(photoBase64 -> {
+                    Map<String, Object> requestParams = new HashMap<>();
+                    requestParams.put("request_id", "035992000119071904311742_" + DateTool.getRequestId());
+                    requestParams.put("appid", "10233937");
+                    requestParams.put("image", photoBase64);
+                    Map<String, Object> options = new HashMap<>();
+                    options.put("scene", scene);
+                    requestParams.put("options", options);
+
+                    // 发送识别请求
+                    return RetrofitHelper.getInstance()
+                            .getRequestApi(ApiService.class)
+                            .getOcrResult(requestParams);
+                })
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new BaseObserver<OcrResult>() {
+                    @Override
+                    public void onSuccess(OcrResult result) {
+                        if (getView() != null) {
+                            getView().dismissLoading();
+                            getView().onOcrResult(result);
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(Throwable e, String errMsg) {
+                        // 装饰器模式
+                        if (getView() != null) {
+                            getView().dismissLoading();
+                            getView().onOcrResult(null);
+                        }
+                    }
+                });
+    }
 
     private int mWidth = SizeTool.SCREEN_WIDTH;
     private int mHeight = SizeTool.SCREEN_HEIGHT;
 
-    protected void setWidthHeight(int width, int height) {
+    public void setWidthHeight(int width, int height) {
         mWidth = width;
         mHeight = height;
     }

+ 36 - 18
app/src/main/java/com/miekir/ocr/ui/camera/wechat/WechatCameraActivity.java

@@ -6,7 +6,7 @@ import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.os.Environment;
 import android.util.Log;
-import android.view.MotionEvent;
+import android.widget.ImageView;
 import android.widget.Toast;
 
 import com.cjt2325.cameralibrary.JCameraView;
@@ -27,8 +27,15 @@ import java.io.File;
  * Description:
  */
 public class WechatCameraActivity extends BaseCameraActivity {
-    private JCameraView jCameraView;
-    private CropView pcv_scan;
+    protected int mLeft;
+    protected int mTop;
+    protected int mRight;
+    protected int mBottom;
+
+    protected JCameraView jCameraView;
+    protected CropView pcv_scan;
+    private boolean mIsFlashOpen = false;
+    private ImageView iv_flash;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -44,7 +51,17 @@ public class WechatCameraActivity extends BaseCameraActivity {
 
     @Override
     public void initViews(Bundle savedInstanceState) {
-        pcv_scan = findViewById(R.id.pcv_scan);
+
+        iv_flash = findViewById(R.id.iv_flash);
+        iv_flash.setOnClickListener(v -> {
+            mIsFlashOpen = !mIsFlashOpen;
+            if (mIsFlashOpen) {
+                iv_flash.setImageResource(R.mipmap.flash_open);
+            } else {
+                iv_flash.setImageResource(R.mipmap.flash_close);
+            }
+        });
+
         jCameraView = (JCameraView) findViewById(R.id.jcameraview);
         //设置视频保存路径
         jCameraView.setSaveVideoPath(Environment.getExternalStorageDirectory().getPath() + File.separator + "JCamera");
@@ -71,12 +88,13 @@ public class WechatCameraActivity extends BaseCameraActivity {
             @Override
             public void captureSuccess(Bitmap bitmap) {
                 //获取图片bitmap
+                takePhotoResult(bitmap);
 //                Log.i("JCameraView", "bitmap = " + bitmap.getWidth());
-                String path = FileUtil.saveBitmap("JCamera", bitmap);
-                Intent intent = new Intent();
-                intent.putExtra("path", path);
-                setResult(101, intent);
-                finish();
+//                String path = FileUtil.saveBitmap("JCamera", bitmap);
+//                Intent intent = new Intent();
+//                intent.putExtra("path", path);
+//                setResult(101, intent);
+//                finish();
             }
 
             @Override
@@ -91,15 +109,11 @@ public class WechatCameraActivity extends BaseCameraActivity {
             }
         });
 
-        pcv_scan.setOnTouchUpListener(new CropView.onTouchUpListener() {
-            @Override
-            public void onTouch(MotionEvent event) {
-                if (event.getPointerCount() == 1) {
-                    //显示对焦指示器
-                    if (jCameraView != null) {
-                        jCameraView.setFocusViewWidthAnimation(event.getX(), event.getY());
-                    }
-                }
+        pcv_scan = findViewById(R.id.pcv_scan);
+        pcv_scan.setOnTouchUpListener(event -> {
+            if (event.getPointerCount() == 1 && jCameraView != null) {
+                // 手动对焦
+                jCameraView.setFocusViewWidthAnimation(event.getX(), event.getY());
             }
         });
     }
@@ -135,4 +149,8 @@ public class WechatCameraActivity extends BaseCameraActivity {
         super.onPause();
         jCameraView.onPause();
     }
+
+    protected void takePhotoResult(Bitmap bitmap) {
+
+    }
 }

+ 316 - 0
app/src/main/java/com/miekir/ocr/ui/camera/wechat/WechatOperationActivity.java

@@ -0,0 +1,316 @@
+package com.miekir.ocr.ui.camera.wechat;
+
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.miekir.common.utils.ToastTool;
+import com.miekir.common.utils.ViewTool;
+import com.miekir.mvp.presenter.InjectPresenter;
+import com.miekir.ocr.R;
+import com.miekir.ocr.bean.OcrResult;
+import com.miekir.ocr.tool.AnimateManager;
+import com.miekir.ocr.tool.SystemTool;
+import com.miekir.ocr.ui.IOperationView;
+import com.miekir.ocr.ui.OperationPresenter;
+import com.miekir.ocr.widget.CropView;
+import com.miekir.ocr.widget.GlideV4ImageEngine;
+import com.miekir.ocr.widget.IndicatorText;
+import com.zhihu.matisse.Matisse;
+import com.zhihu.matisse.MimeType;
+
+import java.io.File;
+import java.util.List;
+
+import static android.os.Environment.DIRECTORY_PICTURES;
+
+/**
+ * Copyright (C), 2019-2020, Genlot
+ *
+ * @author 詹子聪
+ * @date 2020/7/27 9:01
+ * Description: 菜单操作
+ */
+public class WechatOperationActivity extends WechatCameraActivity implements CropView.onLocationListener, View.OnClickListener, IOperationView {
+    private static final int REQUEST_CODE_CHOOSE = 6;
+
+    @InjectPresenter
+    OperationPresenter mOperationPresenter;
+
+    private int mCurrentType = CropView.SCAN_TYPE_ALL;
+    private String mCurrentScene = CropView.SCAN_SCENES[mCurrentType];
+    private int[] MENU_ID_LIST = {R.id.it_postal, R.id.it_address, R.id.it_name, R.id.it_all};
+
+    private TextView tv_orientation;
+    private String mLandscapeString;
+    private String mPortraitString;
+
+
+    @Override
+    public void initViews(Bundle savedInstanceState) {
+        super.initViews(savedInstanceState);
+
+        int[] clickIds = new int[]{R.id.it_postal, R.id.fl_take, R.id.it_address, R.id.it_name, R.id.it_all, R.id.fl_album};
+        ViewTool.setOnClickListener(this, clickIds, this);
+
+        // 裁剪View
+        pcv_scan.setLocationListener(this);
+        //showResultDialog(null);
+        //showLoading("Loading...");
+
+        mLandscapeString = getResources().getString(R.string.landscape);
+        mPortraitString = getResources().getString(R.string.portrait);
+        tv_orientation = findViewById(R.id.tv_orientation);
+        tv_orientation.setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.fl_take:
+                if (jCameraView != null) {
+                    jCameraView.takePhoto();
+                }
+                break;
+            case R.id.fl_album:
+                Matisse.from(this)
+                        .choose(MimeType.ofImage())
+                        .countable(true)
+                        .maxSelectable(1)
+                        //.addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
+                        //.gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size))
+                        .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
+                        .thumbnailScale(0.85f)
+                        //.imageEngine(new GlideEngine())
+                        .imageEngine(new GlideV4ImageEngine())
+                        //.showPreview(false) // Default is `true`
+                        .forResult(REQUEST_CODE_CHOOSE);
+                break;
+
+            case R.id.it_postal:
+            case R.id.it_address:
+            case R.id.it_name:
+            case R.id.it_all:
+                setScanArea(v.getId());
+                if (v.getId() == R.id.it_all) {
+                    tv_orientation.setText(mLandscapeString);
+                    tv_orientation.setVisibility(View.VISIBLE);
+                } else {
+                    tv_orientation.setVisibility(View.INVISIBLE);
+                }
+
+                break;
+
+            case R.id.tv_orientation:
+                String textOld = tv_orientation.getText().toString();
+                if (TextUtils.equals(mLandscapeString, textOld)) {
+                    tv_orientation.setText(mPortraitString);
+                } else {
+                    tv_orientation.setText(mLandscapeString);
+                }
+
+                if (tv_orientation.getVisibility() == View.VISIBLE) {
+                    // 切换横竖屏
+                    AnimateManager.getInstance().stopAnimation();
+                    pcv_scan.switchOrientation();
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * 设置裁剪区域
+     * @param viewId
+     */
+    private void setScanArea(int viewId) {
+        for (int index = 0, len = MENU_ID_LIST.length; index < len; index++) {
+            IndicatorText indicatorText = findViewById(MENU_ID_LIST[index]);
+            if (MENU_ID_LIST[index] == viewId) {
+                indicatorText.onIndicatorClicked();
+                mCurrentType = CropView.SCAN_TYPES[index];
+                mCurrentScene = CropView.SCAN_SCENES[index];
+            } else {
+                indicatorText.onIndicatorRelease();
+            }
+        }
+        pcv_scan.setScanArea(mCurrentType);
+    }
+
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_CHOOSE && data != null) {
+            List<Uri> selectedList = Matisse.obtainResult(data);
+            if (selectedList != null && selectedList.size() > 0) {
+                if (tv_orientation.getVisibility() == View.VISIBLE) {
+                    mOperationPresenter.startOcrFromUri(this, selectedList.get(0), mCurrentScene, pcv_scan.isLandscape());
+                } else {
+                    mOperationPresenter.startOcrFromUri(this, selectedList.get(0), mCurrentScene, false);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void locationRect(int startX, int startY, int endX, int endY) {
+        // 截取的区域坐标信息
+        //System.out.println("x:"+startX + "   y:" + startY + "    endX:" + endX + "   endY" + endY);
+        /*mLeft = startY;
+        mTop = SizeTool.SCREEN_WIDTH - endX;
+        mRight = endY;
+        mBottom = SizeTool.SCREEN_WIDTH - startX;*/
+
+        mLeft = startX;
+        mTop = startY;
+        mRight = endX;
+        mBottom = endY;
+
+        /*mLeft = startY;
+        mTop = SizeTool.SCREEN_WIDTH - endX;
+        mRight = endY;
+        mBottom = SizeTool.SCREEN_WIDTH - startX;*/
+    }
+
+    @Override
+    public void onOcrResult(OcrResult result) {
+        // 识别结果
+        showResultDialog(result);
+    }
+
+    /**
+     * 弹出识别对话框
+     * @param result
+     */
+    private void showResultDialog(OcrResult result) {
+        AlertDialog dialog = new AlertDialog.Builder(this).setView(R.layout.dialog_result).create();
+        dialog.show();
+        dialog.setCancelable(false);
+        dialog.setCanceledOnTouchOutside(false);
+
+        dialog.findViewById(R.id.tv_copy).setOnClickListener(v -> {
+            dialog.cancel();
+            if (result == null) {
+                return;
+            }
+
+            SystemTool.copyText(WechatOperationActivity.this, "");
+            // 复制全部识别信息
+            if (mCurrentType == CropView.SCAN_TYPE_ALL) {
+                StringBuilder builder = new StringBuilder();
+                if (result.postcode != null) {
+                    builder.append(result.postcode.getText()).append(",");
+                }
+                if (result.address != null) {
+                    builder.append(result.address.getText()).append(",");
+                }
+                if (result.name != null) {
+                    builder.append(result.name.getText()).append(",");
+                }
+                if (builder.length() > 0) {
+                    builder.deleteCharAt(builder.length()-1);
+                    SystemTool.copyText(WechatOperationActivity.this, builder.toString());
+                } else {
+                    SystemTool.copyText(WechatOperationActivity.this, " ");
+                }
+            } else if (mCurrentType == CropView.SCAN_TYPE_POSTAL) {
+                if (result.postcode != null) {
+                    SystemTool.copyText(WechatOperationActivity.this, result.postcode.getText());
+                } else {
+                    SystemTool.copyText(WechatOperationActivity.this, " ");
+                }
+            } else if (mCurrentType == CropView.SCAN_TYPE_ADDRESS) {
+                if (result.address != null) {
+                    SystemTool.copyText(WechatOperationActivity.this, result.address.getText());
+                } else {
+                    SystemTool.copyText(WechatOperationActivity.this, " ");
+                }
+            } else if (mCurrentType == CropView.SCAN_TYPE_NAME) {
+                if (result.name != null) {
+                    SystemTool.copyText(WechatOperationActivity.this, result.name.getText());
+                } else {
+                    SystemTool.copyText(WechatOperationActivity.this, " ");
+                }
+            }
+
+            ToastTool.showShort(getString(R.string.copy_success));
+        });
+        dialog.findViewById(R.id.tv_cancel).setOnClickListener(v -> {
+            dialog.cancel();
+        });
+
+        LinearLayout ll_postal = dialog.findViewById(R.id.ll_postal);
+        LinearLayout ll_address = dialog.findViewById(R.id.ll_address);
+        LinearLayout ll_name = dialog.findViewById(R.id.ll_name);
+        if (mCurrentType == CropView.SCAN_TYPE_ALL) {
+            ll_postal.setVisibility(View.VISIBLE);
+            ll_address.setVisibility(View.VISIBLE);
+            ll_name.setVisibility(View.VISIBLE);
+        } else if (mCurrentType == CropView.SCAN_TYPE_POSTAL) {
+            ll_postal.setVisibility(View.VISIBLE);
+            ll_address.setVisibility(View.GONE);
+            ll_name.setVisibility(View.GONE);
+        } else if (mCurrentType == CropView.SCAN_TYPE_ADDRESS) {
+            ll_address.setVisibility(View.VISIBLE);
+            ll_postal.setVisibility(View.GONE);
+            ll_name.setVisibility(View.GONE);
+
+        } else if (mCurrentType == CropView.SCAN_TYPE_NAME) {
+            ll_name.setVisibility(View.VISIBLE);
+            ll_postal.setVisibility(View.GONE);
+            ll_address.setVisibility(View.GONE);
+        }
+
+        TextView tv_postal = dialog.findViewById(R.id.tv_postal);
+        TextView tv_address = dialog.findViewById(R.id.tv_address);
+        TextView tv_name = dialog.findViewById(R.id.tv_name);
+        tv_postal.setText("");
+        tv_address.setText("");
+        tv_name.setText("");
+
+
+        if (result == null) {
+            return;
+        }
+
+        if (result.postcode != null) {
+            tv_postal.setText(result.postcode.getText());
+        }
+
+        if (result.address != null) {
+            tv_address.setText(result.address.getText());
+        }
+
+        if (result.name != null) {
+            tv_name.setText(result.name.getText());
+        }
+    }
+
+    @Override
+    protected void takePhotoResult(Bitmap bitmap) {
+        super.takePhotoResult(bitmap);
+        if (bitmap == null) {
+            return;
+        }
+        // 得到裁剪后的图片数据
+        int[] rectData = new int[]{mLeft, mTop, mRight, mBottom};
+        File file = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + "/" + System.currentTimeMillis() + ".jpg");
+        if (tv_orientation.getVisibility() == View.VISIBLE) {
+            mOperationPresenter.startOcrFromBitmap(this, bitmap, rectData, file, mCurrentScene, pcv_scan.isLandscape());
+        } else {
+            mOperationPresenter.startOcrFromBitmap(this, bitmap, rectData, file, mCurrentScene, false);
+        }
+    }
+}

+ 24 - 19
camera/src/main/java/com/cjt2325/cameralibrary/CaptureLayout.java

@@ -108,15 +108,17 @@ public class CaptureLayout extends FrameLayout {
 
     public void startTypeBtnAnimator() {
         //拍照录制结果后的动画
-        if (this.iconLeft != 0)
+        if (this.iconLeft != 0) {
             iv_custom_left.setVisibility(GONE);
-        else
+        } else {
             btn_return.setVisibility(GONE);
-        if (this.iconRight != 0)
+        }
+        if (this.iconRight != 0) {
             iv_custom_right.setVisibility(GONE);
+        }
         btn_capture.setVisibility(GONE);
-        btn_cancel.setVisibility(VISIBLE);
-        btn_confirm.setVisibility(VISIBLE);
+        btn_cancel.setVisibility(GONE);
+        btn_confirm.setVisibility(GONE);
         btn_cancel.setClickable(false);
         btn_confirm.setClickable(false);
         ObjectAnimator animator_cancel = ObjectAnimator.ofFloat(btn_cancel, "translationX", layout_width / 4, 0);
@@ -191,6 +193,7 @@ public class CaptureLayout extends FrameLayout {
                 }
             }
         });
+        btn_capture.setVisibility(GONE);
 
         //取消按钮
         btn_cancel = new TypeButton(getContext(), TypeButton.TYPE_CANCEL, button_size);
@@ -242,6 +245,7 @@ public class CaptureLayout extends FrameLayout {
         });
         //左边自定义按钮
         iv_custom_left = new ImageView(getContext());
+        iv_custom_left.setVisibility(GONE);
         LayoutParams iv_custom_param_left = new LayoutParams((int) (button_size / 2.5f), (int) (button_size / 2.5f));
         iv_custom_param_left.gravity = Gravity.CENTER_VERTICAL;
         iv_custom_param_left.setMargins(layout_width / 6, 0, 0, 0);
@@ -271,6 +275,7 @@ public class CaptureLayout extends FrameLayout {
         });
 
         txt_tip = new TextView(getContext());
+        txt_tip.setVisibility(GONE);
         LayoutParams txt_param = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
         txt_param.gravity = Gravity.CENTER_HORIZONTAL;
         txt_param.setMargins(0, 0, 0, 0);
@@ -293,16 +298,16 @@ public class CaptureLayout extends FrameLayout {
      * 对外提供的API                      *
      **************************************************/
     public void resetCaptureLayout() {
-        btn_capture.resetState();
-        btn_cancel.setVisibility(GONE);
-        btn_confirm.setVisibility(GONE);
-        btn_capture.setVisibility(VISIBLE);
-        if (this.iconLeft != 0)
-            iv_custom_left.setVisibility(VISIBLE);
-        else
-            btn_return.setVisibility(VISIBLE);
-        if (this.iconRight != 0)
-            iv_custom_right.setVisibility(VISIBLE);
+//        btn_capture.resetState();
+//        btn_cancel.setVisibility(GONE);
+//        btn_confirm.setVisibility(GONE);
+//        btn_capture.setVisibility(GONE);
+//        if (this.iconLeft != 0)
+//            iv_custom_left.setVisibility(GONE);
+//        else
+//            btn_return.setVisibility(GONE);
+//        if (this.iconRight != 0)
+//            iv_custom_right.setVisibility(GONE);
     }
 
 
@@ -335,7 +340,7 @@ public class CaptureLayout extends FrameLayout {
     }
 
     public void showTip() {
-        txt_tip.setVisibility(VISIBLE);
+        txt_tip.setVisibility(GONE);
     }
 
     public void setIconSrc(int iconLeft, int iconRight) {
@@ -343,15 +348,15 @@ public class CaptureLayout extends FrameLayout {
         this.iconRight = iconRight;
         if (this.iconLeft != 0) {
             iv_custom_left.setImageResource(iconLeft);
-            iv_custom_left.setVisibility(VISIBLE);
+//            iv_custom_left.setVisibility(GONE);
             btn_return.setVisibility(GONE);
         } else {
             iv_custom_left.setVisibility(GONE);
-            btn_return.setVisibility(VISIBLE);
+            btn_return.setVisibility(GONE);
         }
         if (this.iconRight != 0) {
             iv_custom_right.setImageResource(iconRight);
-            iv_custom_right.setVisibility(VISIBLE);
+            iv_custom_right.setVisibility(GONE);
         } else {
             iv_custom_right.setVisibility(GONE);
         }

+ 27 - 14
camera/src/main/java/com/cjt2325/cameralibrary/JCameraView.java

@@ -181,23 +181,23 @@ public class JCameraView extends FrameLayout implements CameraInterface.CameraOp
         mCaptureLayout.setCaptureLisenter(new CaptureListener() {
             @Override
             public void takePictures() {
-                mSwitchCamera.setVisibility(INVISIBLE);
-                mFlashLamp.setVisibility(INVISIBLE);
+                mSwitchCamera.setVisibility(GONE);
+                mFlashLamp.setVisibility(GONE);
                 machine.capture();
             }
 
             @Override
             public void recordStart() {
-                mSwitchCamera.setVisibility(INVISIBLE);
-                mFlashLamp.setVisibility(INVISIBLE);
+                mSwitchCamera.setVisibility(GONE);
+                mFlashLamp.setVisibility(GONE);
                 machine.record(mVideoView.getHolder().getSurface(), screenProp);
             }
 
             @Override
             public void recordShort(final long time) {
                 mCaptureLayout.setTextWithAnimation("录制时间过短");
-                mSwitchCamera.setVisibility(VISIBLE);
-                mFlashLamp.setVisibility(VISIBLE);
+//                mSwitchCamera.setVisibility(VISIBLE);
+//                mFlashLamp.setVisibility(VISIBLE);
                 postDelayed(new Runnable() {
                     @Override
                     public void run() {
@@ -364,6 +364,13 @@ public class JCameraView extends FrameLayout implements CameraInterface.CameraOp
         return true;
     }*/
 
+    public void takePhoto() {
+        if (machine == null) {
+            return;
+        }
+        machine.capture();
+    }
+
     //对焦框指示器动画
     public void setFocusViewWidthAnimation(float x, float y) {
         machine.foucs(x, y, new CameraInterface.FocusCallback() {
@@ -427,16 +434,19 @@ public class JCameraView extends FrameLayout implements CameraInterface.CameraOp
                 machine.start(mVideoView.getHolder(), screenProp);
                 break;
             case TYPE_PICTURE:
-                mPhoto.setVisibility(INVISIBLE);
+                mPhoto.setVisibility(GONE);
                 break;
             case TYPE_SHORT:
                 break;
             case TYPE_DEFAULT:
                 mVideoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                 break;
+
+            default:
+                break;
         }
-        mSwitchCamera.setVisibility(VISIBLE);
-        mFlashLamp.setVisibility(VISIBLE);
+//        mSwitchCamera.setVisibility(VISIBLE);
+//        mFlashLamp.setVisibility(VISIBLE);
         mCaptureLayout.resetCaptureLayout();
     }
 
@@ -452,7 +462,7 @@ public class JCameraView extends FrameLayout implements CameraInterface.CameraOp
                 }
                 break;
             case TYPE_PICTURE:
-                mPhoto.setVisibility(INVISIBLE);
+                mPhoto.setVisibility(GONE);
                 if (jCameraLisenter != null) {
                     jCameraLisenter.captureSuccess(captureBitmap);
                 }
@@ -461,6 +471,9 @@ public class JCameraView extends FrameLayout implements CameraInterface.CameraOp
                 break;
             case TYPE_DEFAULT:
                 break;
+
+            default:
+                break;
         }
         mCaptureLayout.resetCaptureLayout();
     }
@@ -473,10 +486,10 @@ public class JCameraView extends FrameLayout implements CameraInterface.CameraOp
             mPhoto.setScaleType(ImageView.ScaleType.FIT_CENTER);
         }
         captureBitmap = bitmap;
-        mPhoto.setImageBitmap(bitmap);
-        mPhoto.setVisibility(VISIBLE);
-        mCaptureLayout.startAlphaAnimation();
-        mCaptureLayout.startTypeBtnAnimator();
+        //mPhoto.setImageBitmap(bitmap);
+        //mPhoto.setVisibility(VISIBLE);
+//        mCaptureLayout.startAlphaAnimation();
+//        mCaptureLayout.startTypeBtnAnimator();
     }
 
     @Override

+ 4 - 1
camera/src/main/java/com/cjt2325/cameralibrary/state/PreviewState.java

@@ -59,8 +59,11 @@ class PreviewState implements State {
         CameraInterface.getInstance().takePicture(new CameraInterface.TakePictureCallback() {
             @Override
             public void captureResult(Bitmap bitmap, boolean isVertical) {
+                //BitmapManager.getInstance().setBitmap(bitmap);
                 machine.getView().showPicture(bitmap, isVertical);
-                machine.setState(machine.getBorrowPictureState());
+                machine.getView().confirmState(JCameraView.TYPE_PICTURE);
+                machine.setState(machine.getPreviewState());
+                //machine.setState(machine.getBorrowPictureState());
                 LogUtil.i("capture");
             }
         });

+ 57 - 0
camera/src/main/java/com/cjt2325/cameralibrary/util/BitmapManager.java

@@ -0,0 +1,57 @@
+package com.cjt2325.cameralibrary.util;
+
+import android.graphics.Bitmap;
+
+
+/**
+ * Copyright (C), 2019-2020, Miekir
+ *
+ * @author Miekir
+ * @date 2020/10/14 10:04
+ * Description:
+ */
+public class BitmapManager {
+    private static volatile BitmapManager instance;
+    private Bitmap bitmap;
+    private ICapture capture;
+
+    private BitmapManager() {
+    }
+
+
+    public static BitmapManager getInstance() {
+        if (instance == null) {
+            init();
+        }
+        return instance;
+    }
+
+    private static synchronized void init() {
+        if (instance == null) {
+            instance = new BitmapManager();
+        }
+    }
+
+    public Bitmap getBitmap() {
+        return bitmap;
+    }
+
+    public void setBitmap(Bitmap bitmap) {
+        this.bitmap = bitmap;
+        if (bitmap != null && capture != null) {
+            capture.takePhotoResult(bitmap);
+        }
+    }
+
+    public ICapture getCapture() {
+        return capture;
+    }
+
+    public void setCapture(ICapture capture) {
+        if (bitmap != null) {
+            bitmap.recycle();
+            bitmap = null;
+        }
+        this.capture = capture;
+    }
+}

+ 14 - 0
camera/src/main/java/com/cjt2325/cameralibrary/util/ICapture.java

@@ -0,0 +1,14 @@
+package com.cjt2325.cameralibrary.util;
+
+import android.graphics.Bitmap;
+
+/**
+ * Copyright (C), 2019-2020, Miekir
+ *
+ * @author Miekir
+ * @date 2020/10/27 18:00
+ * Description:
+ */
+public interface ICapture {
+    void takePhotoResult(Bitmap bitmap);
+}

+ 4 - 2
camera/src/main/res/layout/camera_view.xml

@@ -34,14 +34,16 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_margin="16dp"
-            android:src="@drawable/ic_flash_on"/>
+            android:src="@drawable/ic_flash_on"
+            android:visibility="gone"/>
 
         <ImageView
             android:id="@+id/image_switch"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_margin="16dp"
-            android:src="@drawable/ic_camera"/>
+            android:src="@drawable/ic_camera"
+            android:visibility="gone"/>
 
     </LinearLayout>