詹子聪 5 vuotta sitten
vanhempi
commit
169bbae1cc

+ 24 - 27
app/src/main/java/com/miekir/ocr/OCRApplication.java

@@ -2,9 +2,6 @@ package com.miekir.ocr;
 
 import android.app.Application;
 
-import com.yc.toollib.crash.CrashHandler;
-import com.yc.toollib.crash.CrashListener;
-
 
 /**
  *
@@ -25,29 +22,29 @@ public class OCRApplication extends Application {
 
         //RxActivityResult.register(this);
 
-        CrashHandler.getInstance().init(this, new CrashListener() {
-            /**
-             * 重启app
-             */
-            @Override
-            public void againStartApp() {
-                //CrashToolUtils.reStartApp1(App.this,1000);
-                //CrashToolUtils.reStartApp2(App.this,1000, MainActivity.class);
-                //CrashToolUtils.reStartApp3(AppManager.getAppManager().currentActivity());
-            }
-
-            /**
-             * 自定义上传crash,支持开发者上传自己捕获的crash数据
-             * @param ex                        ex
-             */
-            @Override
-            public void recordException(Throwable ex) {
-                //崩溃文件存储路径:/storage/emulated/0/Android/data/你的包名/cache/crashLogs
-                //崩溃文件存储路径:/storage/emulated/0/Android/data/com.miekir.ocr/cache/crashLogs
-                //崩溃页面截图存储路径:/storage/emulated/0/Android/data/你的包名/cache/crashPics
-                //自定义上传crash,支持开发者上传自己捕获的crash数据
-                //StatService.recordException(getApplication(), ex);
-            }
-        });
+//        CrashHandler.getInstance().init(this, new CrashListener() {
+//            /**
+//             * 重启app
+//             */
+//            @Override
+//            public void againStartApp() {
+//                //CrashToolUtils.reStartApp1(App.this,1000);
+//                //CrashToolUtils.reStartApp2(App.this,1000, MainActivity.class);
+//                //CrashToolUtils.reStartApp3(AppManager.getAppManager().currentActivity());
+//            }
+//
+//            /**
+//             * 自定义上传crash,支持开发者上传自己捕获的crash数据
+//             * @param ex                        ex
+//             */
+//            @Override
+//            public void recordException(Throwable ex) {
+//                //崩溃文件存储路径:/storage/emulated/0/Android/data/你的包名/cache/crashLogs
+//                //崩溃文件存储路径:/storage/emulated/0/Android/data/com.miekir.ocr/cache/crashLogs
+//                //崩溃页面截图存储路径:/storage/emulated/0/Android/data/你的包名/cache/crashPics
+//                //自定义上传crash,支持开发者上传自己捕获的crash数据
+//                //StatService.recordException(getApplication(), ex);
+//            }
+//        });
     }
 }

+ 15 - 12
app/src/main/java/com/miekir/ocr/ui/camera/otalia/OtaOperationActivity.java

@@ -24,9 +24,10 @@ 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.miekir.ocr.widget.cropview.CropView;
+import com.miekir.ocr.widget.OnFingerUpListener;
 import com.zhihu.matisse.Matisse;
 import com.zhihu.matisse.MimeType;
 
@@ -56,7 +57,7 @@ public class OtaOperationActivity extends OtaCameraActivity implements CropView.
     private String mLandscapeString;
     private String mPortraitString;
 
-    protected CropView cv_main;
+    protected CropView pcv_scan;
 
     @Override
     public void initViews(Bundle savedInstanceState) {
@@ -66,16 +67,18 @@ public class OtaOperationActivity extends OtaCameraActivity implements CropView.
         ViewTool.setOnClickListener(this, clickIds, this);
 
         // 裁剪View
-        cv_main = findViewById(R.id.cv_main);
-        cv_main.setLocationListener(this);
-        cv_main.setOnTouchUpListener(new CropView.OnTouchUpListener() {
+        pcv_scan = findViewById(R.id.pcv_scan);
+        pcv_scan.setLocationListener(this);
+        OnFingerUpListener listener = new OnFingerUpListener() {
             @Override
-            public void onTouch(MotionEvent event) {
+            public void onFingerUp(final MotionEvent event) {
                 if (camera != null) {
                     camera.startAutoFocus(event.getX(), event.getY());
                 }
             }
-        });
+        };
+        pcv_scan.setOnFingerUpListener(listener);
+
 
         mLandscapeString = getResources().getString(R.string.landscape);
         mPortraitString = getResources().getString(R.string.portrait);
@@ -128,7 +131,7 @@ public class OtaOperationActivity extends OtaCameraActivity implements CropView.
                 if (tv_orientation.getVisibility() == View.VISIBLE) {
                     // 切换横竖屏
                     AnimateManager.getInstance().stopAnimation();
-                    cv_main.switchOrientation();
+                    pcv_scan.switchOrientation();
                 }
                 break;
             default:
@@ -151,13 +154,13 @@ public class OtaOperationActivity extends OtaCameraActivity implements CropView.
                 indicatorText.onIndicatorRelease();
             }
         }
-        cv_main.setScanArea(mCurrentType);
+        pcv_scan.setScanArea(mCurrentType);
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        cv_main.setLocationListener(null);
+        pcv_scan.setLocationListener(null);
     }
 
     @Override
@@ -167,7 +170,7 @@ public class OtaOperationActivity extends OtaCameraActivity implements CropView.
             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, cv_main.isLandscape());
+                    mOperationPresenter.startOcrFromUri(this, selectedList.get(0), mCurrentScene, pcv_scan.isLandscape());
                 } else {
                     mOperationPresenter.startOcrFromUri(this, selectedList.get(0), mCurrentScene, false);
                 }
@@ -308,7 +311,7 @@ public class OtaOperationActivity extends OtaCameraActivity implements CropView.
         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, cv_main.isLandscape());
+            mOperationPresenter.startOcrFromBitmap(this, bitmap, rectData, file, mCurrentScene, pcv_scan.isLandscape());
         } else {
             mOperationPresenter.startOcrFromBitmap(this, bitmap, rectData, file, mCurrentScene, false);
         }

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

@@ -119,12 +119,12 @@ public class WechatCameraActivity extends BaseCameraActivity {
         });
 
         pcv_scan = findViewById(R.id.pcv_scan);
-        pcv_scan.setOnTouchUpListener(event -> {
-            if (event.getPointerCount() == 1 && jCameraView != null) {
-                // 手动对焦
-                jCameraView.setFocusViewWidthAnimation(event.getX(), event.getY());
-            }
-        });
+//        pcv_scan.setOnFingerUpListener(event -> {
+//            if (event.getPointerCount() == 1 && jCameraView != null) {
+//                // 手动对焦
+//                jCameraView.setFocusViewWidthAnimation(event.getX(), event.getY());
+//            }
+//        });
     }
 
     @Override

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 899 - 363
app/src/main/java/com/miekir/ocr/widget/CropView.java


+ 7 - 0
app/src/main/java/com/miekir/ocr/widget/OnFingerUpListener.java

@@ -0,0 +1,7 @@
+package com.miekir.ocr.widget;
+
+import android.view.MotionEvent;
+
+public interface OnFingerUpListener {
+    public void onFingerUp(MotionEvent event);
+}

+ 625 - 0
app/src/main/java/com/miekir/ocr/widget/crop/CropViewBackup.java

@@ -0,0 +1,625 @@
+package com.miekir.ocr.widget.crop;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+
+import com.miekir.ocr.R;
+import com.miekir.ocr.tool.AnimateManager;
+
+public class CropViewBackup extends View {
+    public static final int SCAN_TYPE_POSTAL = 0;
+    public static final int SCAN_TYPE_ADDRESS = 1;
+    public static final int SCAN_TYPE_NAME = 2;
+    public static final int SCAN_TYPE_ALL = 3;
+    public static final String[] SCAN_SCENES = {"postcode", "address", "name", "all"};
+    public static final int[] SCAN_TYPES = {SCAN_TYPE_POSTAL, SCAN_TYPE_ADDRESS, SCAN_TYPE_NAME, SCAN_TYPE_ALL};
+    private static final String TAG = "CropView";
+
+    private OnRectChangeListener locationListener;/*listen to the Rect */
+    /*listening position changed */
+    //private OnLocationChangeListener changeLocationlistener;
+
+    private int MODE;
+    private static final int MODE_OUTSIDE = 0x000000aa;/*170*/
+    private static final int MODE_INSIDE = 0x000000bb;/*187*/
+    private static final int MODE_POINT = 0X000000cc;/*204*/
+    private static final int MODE_ILLEGAL = 0X000000dd;/*221*/
+
+    private static int minWidth = 150;/*the minimum width of the rectangle*/
+    private static int minHeight = 150;/*the minimum height of the rectangle*/
+
+    private static final float EDGE_WIDTH = 1.8f;
+    // 否触发宽高改变的范围
+    private static final int ACCURACY = 36;/*touch accuracy*/
+
+    // 画角度的笔粗细
+    private static final float CORNER_STROKE = 6.0f;
+
+    private int pointPosition;/*vertex of a rectangle*/
+
+    private int sX;/*start X location*/
+    private int sY;/*start Y location*/
+    private int eX;/*end X location*/
+    private int eY;/*end Y location*/
+
+    private int validStartX;
+    private int validStartY;
+    private int validEndX;
+    private int validEndY;
+
+    private int pressX;/*X coordinate values while finger press*/
+    private int pressY;/*Y coordinate values while finger press*/
+
+    private int memonyX;/*the last time the coordinate values of X*/
+    private int memonyY;/*the last time the coordinate values of Y*/
+
+    private int coverWidth = 200;/*width of selection box*/
+    private int coverHeight = 400;/*height of selection box*/
+
+    private Paint mPaint;
+    private Paint mPaintLine;
+    private Paint mPaintCorner;
+    private Bitmap mBitmapCover;
+    private Bitmap mBitmapRectBlack;
+    private PorterDuffXfermode xfermode;/*paint mode*/
+
+    public CropViewBackup(Context context) {
+        this(context, null);
+    }
+
+    public CropViewBackup(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CropViewBackup(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        // 获取到宽高之后再初始化
+        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                getViewTreeObserver().removeOnGlobalLayoutListener(this);
+
+                BitmapFactory.Options horizontalOptions = new BitmapFactory.Options();
+                BitmapFactory.decodeResource(getResources(), R.mipmap.move_horizontal, horizontalOptions);
+                horizontalOptions.inJustDecodeBounds = true;
+                // 图片放在不同的文件夹下,outHeight会不一样,放在dpi越高的文件夹,值越小
+                minWidth = horizontalOptions.outHeight * 2;
+                minHeight = minWidth;
+                setScanArea(SCAN_TYPE_ALL); //height is ready
+            }
+        });
+        //post(() -> );
+    }
+
+    /**
+     * 设置扫描区域
+     */
+    public void setScanArea(int scanType) {
+        AnimateManager.getInstance().stopAnimation();
+        switch (scanType) {
+            case SCAN_TYPE_POSTAL:
+                // 邮箱
+                coverWidth = (int) (getWidth()*0.815);
+                // 最小高度不能小于图片的高度
+                coverHeight = Math.max(minHeight, (int)(getWidth()*0.3));
+                sX = (getWidth()-coverWidth)/2;
+                sY = (int) (getWidth()*0.177);
+                break;
+            case SCAN_TYPE_ADDRESS:
+            case SCAN_TYPE_NAME:
+                coverWidth = (int) (getWidth()*0.815);
+                coverHeight = (int) (getWidth()*0.625);
+                sX = (getWidth()-coverWidth)/2;
+                sY = (getHeight()-coverHeight)/2;
+                break;
+            case SCAN_TYPE_ALL:
+                isLandscape = true;
+                coverHeight = getHeight();
+                coverWidth = (int) (coverHeight/1.73);
+
+                // 起始位置
+                sX = (getWidth()-coverWidth)/2;
+                sY = 0;
+                break;
+            default:
+                return;
+        }
+
+        init();
+    }
+
+    private boolean isLandscape = true;
+
+    public boolean isLandscape() {
+        return isLandscape;
+    }
+
+    /**
+     * 切换横竖屏
+     */
+    public void switchOrientation() {
+        if (isLandscape) {
+            coverWidth = getWidth();
+            coverHeight = (int) (coverWidth/1.73);
+            isLandscape = false;
+            sX = 0;
+            sY = (getHeight()-coverHeight)/2;
+        } else {
+            coverHeight = getHeight();
+            coverWidth = (int) (coverHeight/1.73);
+            isLandscape = true;
+            sX = (getWidth()-coverWidth)/2;
+            sY = 0;
+        }
+
+
+        // 起始位置
+        init();
+    }
+
+    @SuppressWarnings("deprecation")
+    private void init() {
+
+        WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+        int width = manager.getDefaultDisplay().getWidth();
+        int height = manager.getDefaultDisplay().getHeight();
+        // 遮罩的颜色
+        mBitmapCover = makeBitmap(width, height, getResources().getColor(R.color.black_transparent), 0, 0);
+        mBitmapRectBlack = makeBitmap(coverWidth, coverHeight, 0xff000000, coverWidth, coverHeight);
+
+        eX = sX + coverWidth;
+        eY = sY + coverHeight;
+        pressX = 0;
+        pressY = 0;
+
+        xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
+
+        mPaint = new Paint();
+        mPaint.setAntiAlias(true);
+
+        mPaintLine = new Paint();
+        mPaintLine.setColor(Color.WHITE);
+        mPaintLine.setStrokeWidth(2.0f);
+
+        mPaintCorner = new Paint();
+        mPaintCorner.setColor(getContext().getResources().getColor(R.color.colorPrimary));
+        mPaintCorner.setStrokeWidth(CORNER_STROKE);
+
+        invalidate();
+        // invalidate()重绘树,主线程使用,不会触发onMeasure()方法(控制大小用)。
+        // 如果是View就重绘View,如果是ViewGroup就全部重绘。postInvalidate()同,在子线程使用
+        // requestLayout()和invalidate()相反,只调用measure()和layout()过程,不会调用draw()
+
+        new Handler().postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                if (coverWidth > coverHeight) {
+                    AnimateManager.getInstance().setWidth(coverWidth, coverHeight, sX, sY, eX, eY);
+                } else {
+                    AnimateManager.getInstance().setHeight(coverWidth, coverHeight, sX, sY, eX, eY);
+                }
+            }
+        }, 800);
+    }
+
+    /*生成bitmap*/
+    private Bitmap makeBitmap(int mwidth, int mheight, int resource, int staX, int staY) {
+        Bitmap bm = Bitmap.createBitmap(mwidth, mheight, Bitmap.Config.ARGB_8888);
+        Canvas c = new Canvas(bm);
+        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+        p.setColor(resource);
+        c.drawRect(staX, staY, mwidth, mheight, p);
+        return bm;
+    }
+
+    /*@Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        mPaint.setFilterBitmap(false);
+        int sc = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null,
+                Canvas.ALL_SAVE_FLAG);
+
+        canvas.drawBitmap(mBitmapCover, 0, 0, mPaint);
+        mPaint.setXfermode(xfermode);
+        canvas.drawBitmap(mBitmapRectBlack, sX, sY, mPaint);
+        if (locationListener != null) {
+            locationListener.locationRect(sX, sY, eX, eY);
+        }
+        mPaint.setXfermode(null);
+        canvas.restoreToCount(sc);
+        canvas.drawLine((float) sX - EDGE_WIDTH, (float) sY - EDGE_WIDTH, (float) eX + EDGE_WIDTH, (float) sY - EDGE_WIDTH, mPaintLine);//up
+        canvas.drawLine((float) sX - EDGE_WIDTH, (float) eY + EDGE_WIDTH, (float) eX + EDGE_WIDTH, (float) eY + EDGE_WIDTH, mPaintLine);//down
+        canvas.drawLine((float) sX - EDGE_WIDTH, (float) sY - EDGE_WIDTH, (float) sX - EDGE_WIDTH, (float) eY + EDGE_WIDTH, mPaintLine);//left
+        canvas.drawLine((float) eX + EDGE_WIDTH, (float) sY - EDGE_WIDTH, (float) eX + EDGE_WIDTH, (float) eY + EDGE_WIDTH, mPaintLine);//righ
+    }*/
+
+
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        if (mPaint == null) {
+            return;
+        }
+        mPaint.setFilterBitmap(false);
+        int sc = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null,
+                Canvas.ALL_SAVE_FLAG);
+
+        canvas.drawBitmap(mBitmapCover, 0, 0, mPaint);
+        mPaint.setXfermode(xfermode);
+        canvas.drawBitmap(mBitmapRectBlack, sX, sY, mPaint);
+        if (locationListener != null) {
+            locationListener.locationRect(sX, sY, eX, eY);
+        }
+        mPaint.setXfermode(null);
+        canvas.restoreToCount(sc);
+        //在此加入4个边角...
+        drawCorners(canvas);
+
+        Log.e(TAG, "onDraw, sX:" + sX + ", sY:" + sY + "     eX:" + eX + ", eY:" + eY);
+        validStartX = sX;
+        validStartY = sY;
+        validEndX = eX;
+        validEndY = eY;
+    }
+
+
+
+    /** Draw the corner of crop overlay. */
+    private void drawCorners(Canvas canvas) {
+        if (mPaintCorner != null) {
+            DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
+            //borderCornerThickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, dm);
+            float mBorderCornerLength = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, dm);
+
+            float lineWidth = 0;
+            float cornerWidth = mPaintCorner.getStrokeWidth();
+
+            // for rectangle crop shape we allow the corners to be offset from the borders
+            float w = 0;
+            RectF rect = new RectF(sX, sY, eX, eY);
+            rect.inset(w, w);
+
+            float cornerOffset = -CORNER_STROKE+2;
+            float cornerExtension = cornerWidth / 2 + cornerOffset;
+
+            // Top left
+            canvas.drawLine(
+                    rect.left - cornerOffset,
+                    rect.top - cornerExtension,
+                    rect.left - cornerOffset,
+                    rect.top + mBorderCornerLength,
+                    mPaintCorner);
+            canvas.drawLine(
+                    rect.left - cornerExtension,
+                    rect.top - cornerOffset,
+                    rect.left + mBorderCornerLength,
+                    rect.top - cornerOffset,
+                    mPaintCorner);
+
+            // Top right
+            canvas.drawLine(
+                    rect.right + cornerOffset,
+                    rect.top - cornerExtension,
+                    rect.right + cornerOffset,
+                    rect.top + mBorderCornerLength,
+                    mPaintCorner);
+            canvas.drawLine(
+                    rect.right + cornerExtension,
+                    rect.top - cornerOffset,
+                    rect.right - mBorderCornerLength,
+                    rect.top - cornerOffset,
+                    mPaintCorner);
+
+            // Bottom left
+            canvas.drawLine(
+                    rect.left - cornerOffset,
+                    rect.bottom + cornerExtension,
+                    rect.left - cornerOffset,
+                    rect.bottom - mBorderCornerLength,
+                    mPaintCorner);
+            canvas.drawLine(
+                    rect.left - cornerExtension,
+                    rect.bottom + cornerOffset,
+                    rect.left + mBorderCornerLength,
+                    rect.bottom + cornerOffset,
+                    mPaintCorner);
+
+            // Bottom left
+            canvas.drawLine(
+                    rect.right + cornerOffset,
+                    rect.bottom + cornerExtension,
+                    rect.right + cornerOffset,
+                    rect.bottom - mBorderCornerLength,
+                    mPaintCorner);
+            canvas.drawLine(
+                    rect.right + cornerExtension,
+                    rect.bottom + cornerOffset,
+                    rect.right - mBorderCornerLength,
+                    rect.bottom + cornerOffset,
+                    mPaintCorner);
+        }
+    }
+
+
+
+    @SuppressWarnings("NullableProblems")
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                AnimateManager.getInstance().stopAnimation();
+                //if (changeLocationlistener != null) {
+                //    changeLocationlistener.locationChange("change self");
+                //}
+
+                memonyX = (int) event.getX();
+                memonyY = (int) event.getY();
+                checkMode(memonyX, memonyY);
+                break;
+            case MotionEvent.ACTION_MOVE: {
+                switch (MODE) {
+                    case MODE_ILLEGAL:
+//                        pressX = (int) event.getX();
+//                        pressY = (int) event.getY();
+//                        Log.e(TAG, "mode_illegal, x:" + pressX + ", y:" + pressY);
+//                        recoverFromIllegal(pressX, pressY);
+//                        postInvalidate();
+                        break;
+                    case MODE_OUTSIDE:
+                        //do nothing;
+                        break;
+                    case MODE_INSIDE:
+//                        pressX = (int) event.getX();
+//                        pressY = (int) event.getY();
+//                        Log.e(TAG, "mode_inside, x:" + pressX + ", y:" + pressY);
+//                        moveByTouch(pressX, pressY);
+//                        postInvalidate();
+                        break;
+                    default:
+                        /*MODE_POINT*/
+                        pressX = (int) event.getX();
+                        pressY = (int) event.getY();
+                        Log.e(TAG, "mode_default, x:" + pressX + ", y:" + pressY);
+                        mPaintLine.setColor(getContext().getResources().getColor(R.color.white));
+                        moveByPoint(pressX, pressY);
+                        postInvalidate();
+                        break;
+                }
+            }
+            break;
+            case MotionEvent.ACTION_UP:
+                if (onTouchUpListener != null) {
+                    onTouchUpListener.onTouch(event);
+                }
+                mPaintLine.setColor(Color.WHITE);
+                postInvalidate();
+                Log.e(TAG, "action_up, validStartX:" + validStartX + ", validStartY:" + validStartY + "     validEndX:" + validEndX + ", validEndY:" + validEndY);
+                new Handler().postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (coverWidth > coverHeight) {
+                            AnimateManager.getInstance().setWidth(coverWidth, coverHeight, validStartX, validStartY, validEndX, validEndY);
+                        } else {
+                            AnimateManager.getInstance().setHeight(coverWidth, coverHeight, validStartX, validStartY, validEndX, validEndY);
+                        }
+                    }
+                }, 50);
+                break;
+            default:
+                break;
+        }
+        return true;
+    }
+
+    /*从非法状态恢复,这里处理的是达到最小值后能拉伸放大*/
+    private void recoverFromIllegal(int rx, int ry) {
+        if ((rx > sX && ry > sY) && (rx < eX && ry < eY)) {
+            MODE = MODE_ILLEGAL;
+        } else {
+            MODE = MODE_POINT;
+        }
+    }
+
+    private void checkMode(int cx, int cy) {
+        if (cx > sX+ACCURACY && cx < eX-ACCURACY && cy > sY+ACCURACY && cy < eY-ACCURACY) {
+            MODE = MODE_INSIDE;
+        } else if (nearbyPoint(cx, cy) < 4) {
+            MODE = MODE_POINT;
+        } else {
+            MODE = MODE_OUTSIDE;
+        }
+    }
+
+    /*推断点(inX,inY)是否靠近矩形的4个顶点*/
+    private int nearbyPoint(int inX, int inY) {
+        if ((Math.abs(sX - inX) <= ACCURACY && (Math.abs(inY - sY) <= ACCURACY))) {/*left-up angle*/
+            pointPosition = 0;
+            return 0;
+        }
+        if ((Math.abs(eX - inX) <= ACCURACY && (Math.abs(inY - sY) <= ACCURACY))) {/*right-up  angle*/
+            pointPosition = 1;
+            return 1;
+        }
+        if ((Math.abs(sX - inX) <= ACCURACY && (Math.abs(inY - eY) <= ACCURACY))) {/*left-down angle*/
+            pointPosition = 2;
+            return 2;
+        }
+        if ((Math.abs(eX - inX) <= ACCURACY && (Math.abs(inY - eY) <= ACCURACY))) {/*right-down angle*/
+            pointPosition = 3;
+            return 3;
+        }
+        pointPosition = 100;
+        return 100;
+    }
+
+    /*刷新矩形的坐标*/
+    private void refreshLocation(int isx, int isy, int iex, int iey) {
+        if (isx <= 0) {
+            this.sX = 0;
+        } else {
+            this.sX = isx;
+        }
+
+        if (isy <= 0) {
+            this.sY = 0;
+        } else {
+            this.sY = isy;
+        }
+
+        if (iex >= getWidth()) {
+            this.eX = getWidth();
+        } else {
+            this.eX = iex;
+        }
+
+        if (iey >= getHeight()) {
+            this.eY = getHeight();
+        } else {
+            this.eY = iey;
+        }
+
+        if (iex - isx < minWidth) {
+            this.eX = isx + minWidth;
+        }
+
+        if (iey - isy < minHeight) {
+            this.eY = isy + minHeight;
+        }
+
+    }
+
+    /*矩形随手指移动*/
+    private void moveByTouch(int mx, int my) {/*move center point*/
+        int dX = mx - memonyX;
+        int dY = my - memonyY;
+
+        if (!(eX == getWidth() && dX > 0)) {
+            sX += dX;
+        }
+
+        if (sX < 0) {
+            sX = 0;
+        }
+
+        if (!(eY == getHeight() && dY > 0)) {
+            sY += dY;
+        }
+        if (sY < 0) {
+            sY = 0;
+        }
+
+        eX = sX + coverWidth;
+        if (eX > getWidth()) {
+            eX = getWidth();
+        }
+        eY = sY + coverHeight;
+        if (eY > getHeight()) {
+            eY = getHeight();
+        }
+
+        memonyX = mx;
+        memonyY = my;
+
+    }
+
+    /*检測矩形是否达到最小值*/
+    private boolean checkLegalRect(int cWidth, int cHeight) {
+        return (cWidth > minWidth && cHeight > minHeight);
+    }
+
+    /*点击顶点附近时的缩放处理*/
+    @SuppressWarnings("SuspiciousNameCombination")
+    private void moveByPoint(int bx, int by) {
+        switch (pointPosition) {
+            case 0:/*left-up*/
+                coverWidth = Math.abs(eX - bx);
+                coverHeight = Math.abs(eY - by);
+                //noinspection SuspiciousNameCombination
+                if (!checkLegalRect(coverWidth, coverHeight)) {
+                    MODE = MODE_ILLEGAL;
+                } else {
+                    mBitmapRectBlack = null;
+                    mBitmapRectBlack = makeBitmap(coverWidth, coverHeight, 0xff000000, coverWidth, coverHeight);
+                    refreshLocation(bx, by, eX, eY);
+                }
+                break;
+            case 1:/*right-up*/
+                coverWidth = Math.abs(bx - sX);
+                coverHeight = Math.abs(eY - by);
+                if (!checkLegalRect(coverWidth, coverHeight)) {
+                    MODE = MODE_ILLEGAL;
+                } else {
+                    mBitmapRectBlack = null;
+                    mBitmapRectBlack = makeBitmap(coverWidth, coverHeight, 0xff000000, coverWidth, coverHeight);
+                    refreshLocation(sX, by, bx, eY);
+                }
+                break;
+            case 2:/*left-down*/
+                coverWidth = Math.abs(eX - bx);
+                coverHeight = Math.abs(by - sY);
+                if (!checkLegalRect(coverWidth, coverHeight)) {
+                    MODE = MODE_ILLEGAL;
+                } else {
+                    mBitmapRectBlack = null;
+                    mBitmapRectBlack = makeBitmap(coverWidth, coverHeight, 0xff000000, coverWidth, coverHeight);
+                    refreshLocation(bx, sY, eX, by);
+                }
+                break;
+            case 3:/*right-down*/
+                coverWidth = Math.abs(bx - sX);
+                coverHeight = Math.abs(by - sY);
+                if (!checkLegalRect(coverWidth, coverHeight)) {
+                    MODE = MODE_ILLEGAL;
+                } else {
+                    mBitmapRectBlack = null;
+                    mBitmapRectBlack = makeBitmap(coverWidth, coverHeight, 0xff000000, coverWidth, coverHeight);
+                    refreshLocation(sX, sY, bx, by);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    public void setLocationListener(OnRectChangeListener locationListener) {
+        this.locationListener = locationListener;
+    }
+
+    public interface OnRectChangeListener {
+        public void locationRect(int startX, int startY, int endX, int endY);
+    }
+
+    public interface OnLocationChangeListener {
+        @SuppressWarnings("SameParameterValue")
+        public void locationChange(String msg);
+    }
+
+    private onTouchUpListener onTouchUpListener;
+
+    public void setOnTouchUpListener(CropViewBackup.onTouchUpListener onTouchUpListener) {
+        this.onTouchUpListener = onTouchUpListener;
+    }
+
+    public interface onTouchUpListener {
+        public void onTouch(MotionEvent event);
+    }
+}

+ 11 - 138
app/src/main/java/com/miekir/ocr/widget/cropview/CropView.java

@@ -36,14 +36,14 @@ import com.miekir.ocr.R;
  */
 public class CropView extends AppCompatImageView {
 
-    private final static String TAG = CropView.class.getSimpleName();
-
-    private final static int HANDLE_SIZE = 24;
-    private final static int HANDLE_WIDTH = 2;
-    private final static int FRAME_MIN_SIZE = 50;
-    private final static int FRAME_STROKE_WEIGHT = 1;
-    private final static int GUIDE_STROKE_WEIGHT = 1;
-    private final static float DEFAULT_INITIAL_SCALE = 1f;
+    public final static String TAG = CropView.class.getSimpleName();
+
+    public final static int HANDLE_SIZE = 24;
+    public final static int HANDLE_WIDTH = 2;
+    public final static int FRAME_MIN_SIZE = 50;
+    public final static int FRAME_STROKE_WEIGHT = 1;
+    public final static int GUIDE_STROKE_WEIGHT = 1;
+    public final static float DEFAULT_INITIAL_SCALE = 1f;
     // 颜色值,包含透明度
     private static final int TRANSPARENT = 0x00000000;
     private static final int TRANSLUCENT_WHITE = 0xBBFFFFFF;
@@ -387,23 +387,6 @@ public class CropView extends AppCompatImageView {
         canvas.drawRect(rbRectFHorizontal, mFramePaint);
 
         // 画中部的线
-        /*if (mCropMode == CropModeEnum.FREE) {
-            // 如果当前是自由模式
-            mFramePaint.setStrokeCap(Paint.Cap.ROUND);
-            mFramePaint.setStrokeWidth(mHandleWidth + SizeUtils.dp2px(2));
-
-            float centerX = mFrameRectF.left + mFrameRectF.width() / 2;
-            float centerY = mFrameRectF.top + mFrameRectF.height() / 2;
-
-            canvas.drawLine(centerX - mHandleSize, mFrameRectF.top, (centerX + mHandleSize), mFrameRectF.top,
-                    mFramePaint);
-            canvas.drawLine(centerX - mHandleSize, mFrameRectF.bottom, centerX + mHandleSize, mFrameRectF.bottom,
-                    mFramePaint);
-            canvas.drawLine(mFrameRectF.left, (centerY - mHandleSize), mFrameRectF.left, centerY + mHandleSize,
-                    mFramePaint);
-            canvas.drawLine(mFrameRectF.right, centerY - mHandleSize, mFrameRectF.right, centerY + mHandleSize,
-                    mFramePaint);
-        }*/
     }
 
     /**
@@ -1625,7 +1608,7 @@ public class CropView extends AppCompatImageView {
     public enum CropModeEnum {
         FIT_IMAGE(0), RATIO_2_3(1), RATIO_3_2(2), RATIO_4_3(3), RATIO_3_4(4), SQUARE(5), RATIO_16_9(6), RATIO_9_16(7), FREE(
                 8);
-        private final int ID;
+        public final int ID;
 
         CropModeEnum(int id) {
             ID = id;
@@ -1647,7 +1630,7 @@ public class CropView extends AppCompatImageView {
         ROTATE_90D(90), ROTATE_180D(180), ROTATE_270D(270), ROTATE_M90D(-90), ROTATE_M180D(-180), ROTATE_M270D(-270), ROTATE_0D(
                 0);
 
-        private final int VALUE;
+        public final int VALUE;
 
         RotateDegreesEnum(final int value) {
             this.VALUE = value;
@@ -1667,7 +1650,7 @@ public class CropView extends AppCompatImageView {
      */
     public enum ShowModeEnum {
         SHOW_ALWAYS(1), SHOW_ON_TOUCH(2), NOT_SHOW(3);
-        private final int ID;
+        public final int ID;
 
         ShowModeEnum(final int id) {
             this.ID = id;
@@ -1891,114 +1874,4 @@ public class CropView extends AppCompatImageView {
             }
         };
     }
-
-
-
-
-
-
-
-
-
-
-
-    public static final int SCAN_TYPE_POSTAL = 0;
-    public static final int SCAN_TYPE_ADDRESS = 1;
-    public static final int SCAN_TYPE_NAME = 2;
-    public static final int SCAN_TYPE_ALL = 3;
-    public static final String[] SCAN_SCENES = {"postcode", "address", "name", "all"};
-    public static final int[] SCAN_TYPES = {SCAN_TYPE_POSTAL, SCAN_TYPE_ADDRESS, SCAN_TYPE_NAME, SCAN_TYPE_ALL};
-
-
-    private OnRectChangeListener locationListener;/*listen to the Rect */
-    public void setLocationListener(OnRectChangeListener locationListener) {
-        this.locationListener = locationListener;
-    }
-    public interface OnRectChangeListener {
-        public void locationRect(int startX, int startY, int endX, int endY);
-    }
-
-    private OnTouchUpListener onTouchUpListener;
-    public void setOnTouchUpListener(OnTouchUpListener onTouchUpListener) {
-        this.onTouchUpListener = onTouchUpListener;
-    }
-    public interface OnTouchUpListener {
-        public void onTouch(MotionEvent event);
-    }
-
-    private boolean isLandscape = true;
-
-    public boolean isLandscape() {
-        return isLandscape;
-    }
-
-
-    /**
-     * 设置扫描区域
-     */
-    public void setScanArea(int scanType) {
-//        AnimateManager.getInstance().stopAnimation();
-//        switch (scanType) {
-//            case SCAN_TYPE_POSTAL:
-//                // 邮箱
-//                coverWidth = (int) (getWidth()*0.815);
-//                // 最小高度不能小于图片的高度
-//                coverHeight = Math.max(minHeight, (int)(getWidth()*0.3));
-//                sX = (getWidth()-coverWidth)/2;
-//                sY = (int) (getWidth()*0.177);
-//                break;
-//            case SCAN_TYPE_ADDRESS:
-//            case SCAN_TYPE_NAME:
-//                coverWidth = (int) (getWidth()*0.815);
-//                coverHeight = (int) (getWidth()*0.625);
-//                sX = (getWidth()-coverWidth)/2;
-//                sY = (getHeight()-coverHeight)/2;
-//                break;
-//            case SCAN_TYPE_ALL:
-//                isLandscape = true;
-//                coverHeight = getHeight();
-//                coverWidth = (int) (coverHeight/1.73);
-//
-//                // 起始位置
-//                sX = (getWidth()-coverWidth)/2;
-//                sY = 0;
-//                break;
-//            default:
-//                return;
-//        }
-//
-//        init();
-    }
-
-    /**
-     * 切换横竖屏
-     */
-    public void switchOrientation() {
-//        if (isLandscape) {
-//            coverWidth = getWidth();
-//            coverHeight = (int) (coverWidth/1.73);
-//            isLandscape = false;
-//            sX = 0;
-//            sY = (getHeight()-coverHeight)/2;
-//        } else {
-//            coverHeight = getHeight();
-//            coverWidth = (int) (coverHeight/1.73);
-//            isLandscape = true;
-//            sX = (getWidth()-coverWidth)/2;
-//            sY = 0;
-//        }
-//
-//
-//        // 起始位置
-//        init();
-    }
-
-
-
-
-
-
-
-
-
 }

+ 3 - 23
app/src/main/res/layout/activity_otalia_camera.xml

@@ -84,30 +84,10 @@
                 android:layout_height="0dp"
                 android:layout_weight="370">
                 <!--灰色遮罩-->
-                <com.miekir.ocr.widget.cropview.CropView
-                    android:id="@+id/cv_main"
+                <com.miekir.ocr.widget.CropView
+                    android:id="@+id/pcv_scan"
                     android:layout_width="match_parent"
-                    android:layout_height="583dp"
-                    android:layout_above="@+id/rv"
-                    android:layout_alignParentTop="true"
-                    android:layout_centerHorizontal="true"
-                    android:padding="10dp"
-                    app:crop_enabled="true"
-                    app:crop_mode="free"
-                    app:background_color="#66FFFFFF"
-                    app:frame_color="@android:color/white"
-                    app:frame_stroke_weight="2dp"
-                    app:guide_color="@android:color/transparent"
-                    app:guide_show_mode="show_always"
-                    app:guide_stroke_weight="2dp"
-                    app:handle_color="@android:color/white"
-                    app:handle_show_mode="show_always"
-                    app:handle_size="24dp"
-                    app:handle_width="3dp"
-                    app:initial_frame_scale="1"
-                    app:min_frame_size="100dp"
-                    app:overlay_color="#AA1C1C1C"
-                    app:touch_padding="8dp" />
+                    android:layout_height="match_parent"/>
 
                 <com.miekir.ocr.widget.ScalableImageView
                     android:id="@+id/iv_animation"