詹子聪 5 lat temu
rodzic
commit
b96be9d3bf
36 zmienionych plików z 27 dodań i 7871 usunięć
  1. 3 2
      app/build.gradle
  2. 1 3
      app/src/main/java/com/miekir/OCRApplication.java
  3. 3 3
      app/src/main/java/com/miekir/ocr/CameraActivity.java
  4. 4 11
      app/src/main/java/com/miekir/ocr/MainActivity.java
  5. 0 3
      app/src/main/java/com/miekir/ocr/base/BaseCameraActivity.java
  6. 0 39
      app/src/main/java/com/miekir/ocr/tool/OverlayTool.java
  7. 4 4
      app/src/main/java/com/miekir/ocr/view/PhotoCropView.java
  8. 5 5
      app/src/main/java/com/miekir/ocr/view/rect/CustomLayout.java
  9. 1 1
      app/src/main/java/com/miekir/ocr/view/rect/CustomDrawable.java
  10. 0 300
      app/src/main/java/com/miekir/ocr/view/cropper/BitmapCroppingWorkerTask.java
  11. 0 150
      app/src/main/java/com/miekir/ocr/view/cropper/BitmapLoadingWorkerTask.java
  12. 0 877
      app/src/main/java/com/miekir/ocr/view/cropper/BitmapUtils.java
  13. 0 1020
      app/src/main/java/com/miekir/ocr/view/cropper/CropImage.java
  14. 0 352
      app/src/main/java/com/miekir/ocr/view/cropper/CropImageActivity.java
  15. 0 123
      app/src/main/java/com/miekir/ocr/view/cropper/CropImageAnimation.java
  16. 0 471
      app/src/main/java/com/miekir/ocr/view/cropper/CropImageOptions.java
  17. 0 2140
      app/src/main/java/com/miekir/ocr/view/cropper/CropImageView.java
  18. 0 1043
      app/src/main/java/com/miekir/ocr/view/cropper/CropOverlayView.java
  19. 0 373
      app/src/main/java/com/miekir/ocr/view/cropper/CropWindowHandler.java
  20. 0 766
      app/src/main/java/com/miekir/ocr/view/cropper/CropWindowMoveHandler.java
  21. BIN
      app/src/main/res/drawable-xxhdpi/crop_image_menu_flip.png
  22. BIN
      app/src/main/res/drawable-xxhdpi/crop_image_menu_rotate_left.png
  23. BIN
      app/src/main/res/drawable-xxhdpi/crop_image_menu_rotate_right.png
  24. 1 1
      app/src/main/res/layout/activity_camera.xml
  25. 0 7
      app/src/main/res/layout/activity_main.xml
  26. 0 6
      app/src/main/res/layout/crop_image_activity.xml
  27. 0 27
      app/src/main/res/layout/crop_image_view.xml
  28. 2 2
      app/src/main/res/layout/view_crop.xml
  29. 0 35
      app/src/main/res/menu/crop_image_menu.xml
  30. 1 11
      app/src/main/res/values/strings.xml
  31. 0 27
      common/src/androidTest/java/com/genlot/common/ExampleInstrumentedTest.java
  32. 1 4
      common/src/androidTest/java/com/miekir/common/ExampleInstrumentedTest.java
  33. 0 17
      common/src/test/java/com/genlot/common/ExampleUnitTest.java
  34. 0 27
      network/src/androidTest/java/com/genlot/network/ExampleInstrumentedTest.java
  35. 1 4
      network/src/androidTest/java/com/miekir/network/ExampleInstrumentedTest.java
  36. 0 17
      network/src/test/java/com/genlot/network/ExampleUnitTest.java

+ 3 - 2
app/build.gradle

@@ -38,14 +38,15 @@ dependencies {
     implementation project(path: ':adapter')
 
     // 权限申请
-    //implementation 'com.github.tbruyelle:rxpermissions:0.12'
     compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.8.1@aar'
 
     // 裁剪图片
     //compile 'com.isseiaoki:simplecropview:1.1.8'
+    //api 'com.theartofdev.edmodo:android-image-cropper:2.8.+'
 
     // 图片选择
     implementation 'com.zhihu.android:matisse:0.5.2'
 
-    implementation 'com.github.VictorAlbertos:RxActivityResult:0.5.0-2.x'
+    //startActivityForResult
+    //implementation 'com.github.VictorAlbertos:RxActivityResult:0.5.0-2.x'
 }

+ 1 - 3
app/src/main/java/com/miekir/OCRApplication.java

@@ -2,10 +2,8 @@ package com.miekir;
 
 import android.app.Application;
 
-import rx_activity_result2.RxActivityResult;
 
 /**
- * Copyright (C), 2019-2020, Genlot
  *
  * @author 詹子聪
  * @date 2020/7/26 11:52
@@ -16,6 +14,6 @@ public class OCRApplication extends Application {
     public void onCreate() {
         super.onCreate();
 
-        RxActivityResult.register(this);
+        //RxActivityResult.register(this);
     }
 }

+ 3 - 3
app/src/main/java/com/miekir/ocr/CameraActivity.java

@@ -39,8 +39,8 @@ import androidx.annotation.Nullable;
 import com.miekir.ocr.base.BaseCameraActivity;
 import com.miekir.ocr.tool.CameraPreviewTool;
 import com.miekir.ocr.view.AutoFitTextureView;
+import com.miekir.ocr.view.CropView;
 import com.miekir.ocr.view.GlideV4ImageEngine;
-import com.miekir.ocr.view.PhotoCropView;
 import com.zhihu.matisse.Matisse;
 import com.zhihu.matisse.MimeType;
 
@@ -59,7 +59,7 @@ import java.util.concurrent.TimeUnit;
 
 import static android.os.Environment.DIRECTORY_PICTURES;
 
-public class CameraActivity extends BaseCameraActivity implements View.OnClickListener, PhotoCropView.onLocationListener {
+public class CameraActivity extends BaseCameraActivity implements View.OnClickListener, CropView.onLocationListener {
     private static final int REQUEST_CODE_CHOOSE = 6;
     private CameraManager mCameraManager;
 
@@ -155,7 +155,7 @@ public class CameraActivity extends BaseCameraActivity implements View.OnClickLi
 
         findViewById(R.id.fl_take).setOnClickListener(this);
         findViewById(R.id.iv_album).setOnClickListener(this);
-        PhotoCropView pcv_scan = findViewById(R.id.pcv_scan);
+        CropView pcv_scan = findViewById(R.id.pcv_scan);
         pcv_scan.setLocationListener(this);
     }
 

+ 4 - 11
app/src/main/java/com/miekir/ocr/MainActivity.java

@@ -3,22 +3,17 @@ package com.miekir.ocr;
 import android.Manifest;
 import android.annotation.SuppressLint;
 import android.content.Intent;
-import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Bundle;
-import android.view.ViewTreeObserver;
 
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
 import androidx.appcompat.app.AppCompatActivity;
 
-import com.miekir.ocr.view.cropper.CropImageView;
 import com.tbruyelle.rxpermissions2.RxPermissions;
 
-import rx_activity_result2.RxActivityResult;
 
 /**
- * Copyright (C), 2019-2020, Genlot
  *
  * @author 詹子聪
  * @date 2020/7/25 20:33
@@ -67,7 +62,7 @@ public class MainActivity extends AppCompatActivity {
      * 打开相册
      */
     private void photoSelect() {
-        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+        /*Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.setType("image/jpeg");
         RxActivityResult.on(this)
@@ -75,13 +70,11 @@ public class MainActivity extends AppCompatActivity {
                 .filter(result -> result.data() != null)
                 .map(result -> result.data().getData())
                 .doOnNext(this::getUri)
-                .subscribe();
+                .subscribe();*/
     }
 
     private void getUri(Uri uri) {
-        CropImageView cropImageView = findViewById(R.id.cropImageView);
-        //cropImageView.setImageUriAsync(uri);
-        cropImageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+        /*cropImageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
             @Override
             public void onGlobalLayout() {
                 cropImageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
@@ -90,6 +83,6 @@ public class MainActivity extends AppCompatActivity {
                 Bitmap bitmap = Bitmap.createBitmap(cropImageView.getWidth(), cropImageView.getHeight(), conf);
                 cropImageView.setImageBitmap(bitmap);
             }
-        });
+        });*/
     }
 }

+ 0 - 3
app/src/main/java/com/miekir/ocr/base/BaseCameraActivity.java

@@ -1,11 +1,8 @@
 package com.miekir.ocr.base;
 
-import androidx.appcompat.app.AlertDialog;
-
 import com.miekir.mvp.view.BaseMVPActivity;
 
 /**
- * Copyright (C), 2019-2020, Genlot
  *
  * @author 詹子聪
  * @date 2020/7/25 20:18

+ 0 - 39
app/src/main/java/com/miekir/ocr/tool/OverlayTool.java

@@ -1,39 +0,0 @@
-package com.miekir.ocr.tool;
-
-import com.miekir.ocr.view.cropper.CropImageOptions;
-import com.miekir.ocr.view.cropper.CropImageView;
-
-/**
- * Copyright (C), 2019-2020, Genlot
- *
- * @author 詹子聪
- * @date 2020/7/26 22:15
- * Description: 遮罩层工具
- */
-public class OverlayTool {
-    public static CropImageOptions getOverlayOptions() {
-        CropImageOptions options = new CropImageOptions();
-        options.fixAspectRatio = false;
-        options.aspectRatioX = 1;
-        options.aspectRatioY = 1;
-        options.scaleType = CropImageView.ScaleType.FIT_CENTER;
-        options.autoZoomEnabled = false;
-        options.multiTouchEnabled = false;
-        options.maxZoom = 1;
-        options.cropShape = CropImageView.CropShape.RECTANGLE;
-        options.guidelines = CropImageView.Guidelines.ON_TOUCH;
-        options.snapRadius = 9.0f;
-        options.touchRadius = 72.0f;
-        options.initialCropWindowPaddingRatio = 0.1f;
-        options.borderLineThickness = 0.0f;
-        options.borderCornerThickness = 6.0f;
-        options.borderCornerOffset = 0.0f;
-        options.guidelinesThickness = 0.0f;
-        options.showCropOverlay = true;
-        options.flipHorizontally = false;
-        options.flipVertically = false;
-        options.validate();
-
-        return options;
-    }
-}

+ 4 - 4
app/src/main/java/com/miekir/ocr/view/PhotoCropView.java

@@ -18,7 +18,7 @@ import android.view.WindowManager;
 
 import com.miekir.ocr.R;
 
-public class PhotoCropView extends View {
+public class CropView extends View {
     public static final int SCAN_TYPE_EMAIL = 0;
     public static final int SCAN_TYPE_ADDRESS_NAME = 1;
     public static final int SCAN_TYPE_ALL = 2;
@@ -65,15 +65,15 @@ public class PhotoCropView extends View {
     private Bitmap mBitmapRectBlack;
     private PorterDuffXfermode xfermode;/*paint mode*/
 
-    public PhotoCropView(Context context) {
+    public CropView(Context context) {
         this(context, null);
     }
 
-    public PhotoCropView(Context context, AttributeSet attrs) {
+    public CropView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
-    public PhotoCropView(Context context, AttributeSet attrs, int defStyleAttr) {
+    public CropView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
 
         // 获取到宽高之后再初始化

+ 5 - 5
app/src/main/java/com/miekir/ocr/view/rect/CustomLayout.java

@@ -1,4 +1,4 @@
-package com.miekir.ocr.view.rect;
+package com.miekir.ocr.view.crop;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
@@ -32,23 +32,23 @@ import com.miekir.ocr.R;
  *
  * </com.miekir.ocr.view.rect.CustomLayout>
  */
-public class CustomLayout extends FrameLayout {
+public class CropLayout extends FrameLayout {
 
     private Context mContext;
     private CustomDrawable background;
 
-    public CustomLayout(@NonNull Context context) {
+    public CropLayout(@NonNull Context context) {
         super(context);
         initView(context, null, 0);
     }
 
-    public CustomLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
+    public CropLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
         this.mContext=context;
         initView(context, attrs, 0);
     }
 
-    public CustomLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+    public CropLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         initView(context, attrs, defStyleAttr);
     }

+ 1 - 1
app/src/main/java/com/miekir/ocr/view/rect/CustomDrawable.java

@@ -1,4 +1,4 @@
-package com.miekir.ocr.view.rect;
+package com.miekir.ocr.view.crop;
 
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;

+ 0 - 300
app/src/main/java/com/miekir/ocr/view/cropper/BitmapCroppingWorkerTask.java

@@ -1,300 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth,
-// inexhaustible as the great rivers.
-// When they come to an end,
-// they begin again,
-// like the days and months;
-// they die and are reborn,
-// like the four seasons."
-//
-// - Sun Tsu,
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.AsyncTask;
-
-import java.lang.ref.WeakReference;
-
-/** Task to crop bitmap asynchronously from the UI thread. */
-final class BitmapCroppingWorkerTask
-    extends AsyncTask<Void, Void, BitmapCroppingWorkerTask.Result> {
-
-  // region: Fields and Consts
-
-  /** Use a WeakReference to ensure the ImageView can be garbage collected */
-  private final WeakReference<CropImageView> mCropImageViewReference;
-
-  /** the bitmap to crop */
-  private final Bitmap mBitmap;
-
-  /** The Android URI of the image to load */
-  private final Uri mUri;
-
-  /** The context of the crop image view widget used for loading of bitmap by Android URI */
-  private final Context mContext;
-
-  /** Required cropping 4 points (x0,y0,x1,y1,x2,y2,x3,y3) */
-  private final float[] mCropPoints;
-
-  /** Degrees the image was rotated after loading */
-  private final int mDegreesRotated;
-
-  /** the original width of the image to be cropped (for image loaded from URI) */
-  private final int mOrgWidth;
-
-  /** the original height of the image to be cropped (for image loaded from URI) */
-  private final int mOrgHeight;
-
-  /** is there is fixed aspect ratio for the crop rectangle */
-  private final boolean mFixAspectRatio;
-
-  /** the X aspect ration of the crop rectangle */
-  private final int mAspectRatioX;
-
-  /** the Y aspect ration of the crop rectangle */
-  private final int mAspectRatioY;
-
-  /** required width of the cropping image */
-  private final int mReqWidth;
-
-  /** required height of the cropping image */
-  private final int mReqHeight;
-
-  /** is the image flipped horizontally */
-  private final boolean mFlipHorizontally;
-
-  /** is the image flipped vertically */
-  private final boolean mFlipVertically;
-
-  /** The option to handle requested width/height */
-  private final CropImageView.RequestSizeOptions mReqSizeOptions;
-
-  /** the Android Uri to save the cropped image to */
-  private final Uri mSaveUri;
-
-  /** the compression format to use when writing the image */
-  private final Bitmap.CompressFormat mSaveCompressFormat;
-
-  /** the quality (if applicable) to use when writing the image (0 - 100) */
-  private final int mSaveCompressQuality;
-  // endregion
-
-  BitmapCroppingWorkerTask(
-      CropImageView cropImageView,
-      Bitmap bitmap,
-      float[] cropPoints,
-      int degreesRotated,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY,
-      int reqWidth,
-      int reqHeight,
-      boolean flipHorizontally,
-      boolean flipVertically,
-      CropImageView.RequestSizeOptions options,
-      Uri saveUri,
-      Bitmap.CompressFormat saveCompressFormat,
-      int saveCompressQuality) {
-
-    mCropImageViewReference = new WeakReference<>(cropImageView);
-    mContext = cropImageView.getContext();
-    mBitmap = bitmap;
-    mCropPoints = cropPoints;
-    mUri = null;
-    mDegreesRotated = degreesRotated;
-    mFixAspectRatio = fixAspectRatio;
-    mAspectRatioX = aspectRatioX;
-    mAspectRatioY = aspectRatioY;
-    mReqWidth = reqWidth;
-    mReqHeight = reqHeight;
-    mFlipHorizontally = flipHorizontally;
-    mFlipVertically = flipVertically;
-    mReqSizeOptions = options;
-    mSaveUri = saveUri;
-    mSaveCompressFormat = saveCompressFormat;
-    mSaveCompressQuality = saveCompressQuality;
-    mOrgWidth = 0;
-    mOrgHeight = 0;
-  }
-
-  BitmapCroppingWorkerTask(
-      CropImageView cropImageView,
-      Uri uri,
-      float[] cropPoints,
-      int degreesRotated,
-      int orgWidth,
-      int orgHeight,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY,
-      int reqWidth,
-      int reqHeight,
-      boolean flipHorizontally,
-      boolean flipVertically,
-      CropImageView.RequestSizeOptions options,
-      Uri saveUri,
-      Bitmap.CompressFormat saveCompressFormat,
-      int saveCompressQuality) {
-
-    mCropImageViewReference = new WeakReference<>(cropImageView);
-    mContext = cropImageView.getContext();
-    mUri = uri;
-    mCropPoints = cropPoints;
-    mDegreesRotated = degreesRotated;
-    mFixAspectRatio = fixAspectRatio;
-    mAspectRatioX = aspectRatioX;
-    mAspectRatioY = aspectRatioY;
-    mOrgWidth = orgWidth;
-    mOrgHeight = orgHeight;
-    mReqWidth = reqWidth;
-    mReqHeight = reqHeight;
-    mFlipHorizontally = flipHorizontally;
-    mFlipVertically = flipVertically;
-    mReqSizeOptions = options;
-    mSaveUri = saveUri;
-    mSaveCompressFormat = saveCompressFormat;
-    mSaveCompressQuality = saveCompressQuality;
-    mBitmap = null;
-  }
-
-  /** The Android URI that this task is currently loading. */
-  public Uri getUri() {
-    return mUri;
-  }
-
-  /**
-   * Crop image in background.
-   *
-   * @param params ignored
-   * @return the decoded bitmap data
-   */
-  @Override
-  protected Result doInBackground(Void... params) {
-    try {
-      if (!isCancelled()) {
-
-        BitmapUtils.BitmapSampled bitmapSampled;
-        if (mUri != null) {
-          bitmapSampled =
-              BitmapUtils.cropBitmap(
-                  mContext,
-                  mUri,
-                  mCropPoints,
-                  mDegreesRotated,
-                  mOrgWidth,
-                  mOrgHeight,
-                  mFixAspectRatio,
-                  mAspectRatioX,
-                  mAspectRatioY,
-                  mReqWidth,
-                  mReqHeight,
-                  mFlipHorizontally,
-                  mFlipVertically);
-        } else if (mBitmap != null) {
-          bitmapSampled =
-              BitmapUtils.cropBitmapObjectHandleOOM(
-                  mBitmap,
-                  mCropPoints,
-                  mDegreesRotated,
-                  mFixAspectRatio,
-                  mAspectRatioX,
-                  mAspectRatioY,
-                  mFlipHorizontally,
-                  mFlipVertically);
-        } else {
-          return new Result((Bitmap) null, 1);
-        }
-
-        Bitmap bitmap =
-            BitmapUtils.resizeBitmap(bitmapSampled.bitmap, mReqWidth, mReqHeight, mReqSizeOptions);
-
-        if (mSaveUri == null) {
-          return new Result(bitmap, bitmapSampled.sampleSize);
-        } else {
-          BitmapUtils.writeBitmapToUri(
-              mContext, bitmap, mSaveUri, mSaveCompressFormat, mSaveCompressQuality);
-          if (bitmap != null) {
-            bitmap.recycle();
-          }
-          return new Result(mSaveUri, bitmapSampled.sampleSize);
-        }
-      }
-      return null;
-    } catch (Exception e) {
-      return new Result(e, mSaveUri != null);
-    }
-  }
-
-  /**
-   * Once complete, see if ImageView is still around and set bitmap.
-   *
-   * @param result the result of bitmap cropping
-   */
-  @Override
-  protected void onPostExecute(Result result) {
-    if (result != null) {
-      boolean completeCalled = false;
-      if (!isCancelled()) {
-        CropImageView cropImageView = mCropImageViewReference.get();
-        if (cropImageView != null) {
-          completeCalled = true;
-          cropImageView.onImageCroppingAsyncComplete(result);
-        }
-      }
-      if (!completeCalled && result.bitmap != null) {
-        // fast release of unused bitmap
-        result.bitmap.recycle();
-      }
-    }
-  }
-
-  // region: Inner class: Result
-
-  /** The result of BitmapCroppingWorkerTask async loading. */
-  static final class Result {
-
-    /** The cropped bitmap */
-    public final Bitmap bitmap;
-
-    /** The saved cropped bitmap uri */
-    public final Uri uri;
-
-    /** The error that occurred during async bitmap cropping. */
-    final Exception error;
-
-    /** is the cropping request was to get a bitmap or to save it to uri */
-    final boolean isSave;
-
-    /** sample size used creating the crop bitmap to lower its size */
-    final int sampleSize;
-
-    Result(Bitmap bitmap, int sampleSize) {
-      this.bitmap = bitmap;
-      this.uri = null;
-      this.error = null;
-      this.isSave = false;
-      this.sampleSize = sampleSize;
-    }
-
-    Result(Uri uri, int sampleSize) {
-      this.bitmap = null;
-      this.uri = uri;
-      this.error = null;
-      this.isSave = true;
-      this.sampleSize = sampleSize;
-    }
-
-    Result(Exception error, boolean isSave) {
-      this.bitmap = null;
-      this.uri = null;
-      this.error = error;
-      this.isSave = isSave;
-      this.sampleSize = 1;
-    }
-  }
-  // endregion
-}

+ 0 - 150
app/src/main/java/com/miekir/ocr/view/cropper/BitmapLoadingWorkerTask.java

@@ -1,150 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth,
-// inexhaustible as the great rivers.
-// When they come to an end,
-// they begin again,
-// like the days and months;
-// they die and are reborn,
-// like the four seasons."
-//
-// - Sun Tsu,
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.util.DisplayMetrics;
-
-import java.lang.ref.WeakReference;
-
-/** Task to load bitmap asynchronously from the UI thread. */
-final class BitmapLoadingWorkerTask extends AsyncTask<Void, Void, BitmapLoadingWorkerTask.Result> {
-
-  // region: Fields and Consts
-
-  /** Use a WeakReference to ensure the ImageView can be garbage collected */
-  private final WeakReference<CropImageView> mCropImageViewReference;
-
-  /** The Android URI of the image to load */
-  private final Uri mUri;
-
-  /** The context of the crop image view widget used for loading of bitmap by Android URI */
-  private final Context mContext;
-
-  /** required width of the cropping image after density adjustment */
-  private final int mWidth;
-
-  /** required height of the cropping image after density adjustment */
-  private final int mHeight;
-  // endregion
-
-  public BitmapLoadingWorkerTask(CropImageView cropImageView, Uri uri) {
-    mUri = uri;
-    mCropImageViewReference = new WeakReference<>(cropImageView);
-
-    mContext = cropImageView.getContext();
-
-    DisplayMetrics metrics = cropImageView.getResources().getDisplayMetrics();
-    double densityAdj = metrics.density > 1 ? 1 / metrics.density : 1;
-    mWidth = (int) (metrics.widthPixels * densityAdj);
-    mHeight = (int) (metrics.heightPixels * densityAdj);
-  }
-
-  /** The Android URI that this task is currently loading. */
-  public Uri getUri() {
-    return mUri;
-  }
-
-  /**
-   * Decode image in background.
-   *
-   * @param params ignored
-   * @return the decoded bitmap data
-   */
-  @Override
-  protected Result doInBackground(Void... params) {
-    try {
-      if (!isCancelled()) {
-
-        BitmapUtils.BitmapSampled decodeResult =
-            BitmapUtils.decodeSampledBitmap(mContext, mUri, mWidth, mHeight);
-
-        if (!isCancelled()) {
-
-          BitmapUtils.RotateBitmapResult rotateResult =
-              BitmapUtils.rotateBitmapByExif(decodeResult.bitmap, mContext, mUri);
-
-          return new Result(
-              mUri, rotateResult.bitmap, decodeResult.sampleSize, rotateResult.degrees);
-        }
-      }
-      return null;
-    } catch (Exception e) {
-      return new Result(mUri, e);
-    }
-  }
-
-  /**
-   * Once complete, see if ImageView is still around and set bitmap.
-   *
-   * @param result the result of bitmap loading
-   */
-  @Override
-  protected void onPostExecute(Result result) {
-    if (result != null) {
-      boolean completeCalled = false;
-      if (!isCancelled()) {
-        CropImageView cropImageView = mCropImageViewReference.get();
-        if (cropImageView != null) {
-          completeCalled = true;
-          cropImageView.onSetImageUriAsyncComplete(result);
-        }
-      }
-      if (!completeCalled && result.bitmap != null) {
-        // fast release of unused bitmap
-        result.bitmap.recycle();
-      }
-    }
-  }
-
-  // region: Inner class: Result
-
-  /** The result of BitmapLoadingWorkerTask async loading. */
-  public static final class Result {
-
-    /** The Android URI of the image to load */
-    public final Uri uri;
-
-    /** The loaded bitmap */
-    public final Bitmap bitmap;
-
-    /** The sample size used to load the given bitmap */
-    public final int loadSampleSize;
-
-    /** The degrees the image was rotated */
-    public final int degreesRotated;
-
-    /** The error that occurred during async bitmap loading. */
-    public final Exception error;
-
-    Result(Uri uri, Bitmap bitmap, int loadSampleSize, int degreesRotated) {
-      this.uri = uri;
-      this.bitmap = bitmap;
-      this.loadSampleSize = loadSampleSize;
-      this.degreesRotated = degreesRotated;
-      this.error = null;
-    }
-
-    Result(Uri uri, Exception error) {
-      this.uri = uri;
-      this.bitmap = null;
-      this.loadSampleSize = 0;
-      this.degreesRotated = 0;
-      this.error = error;
-    }
-  }
-  // endregion
-}

+ 0 - 877
app/src/main/java/com/miekir/ocr/view/cropper/BitmapUtils.java

@@ -1,877 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth,
-// inexhaustible as the great rivers.
-// When they come to an end,
-// they begin again,
-// like the days and months;
-// they die and are reborn,
-// like the four seasons."
-//
-// - Sun Tsu,
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.net.Uri;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.ref.WeakReference;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-
-import androidx.exifinterface.media.ExifInterface;
-
-/** Utility class that deals with operations with an ImageView. */
-final class BitmapUtils {
-
-  static final Rect EMPTY_RECT = new Rect();
-
-  static final RectF EMPTY_RECT_F = new RectF();
-
-  /** Reusable rectangle for general internal usage */
-  static final RectF RECT = new RectF();
-
-  /** Reusable point for general internal usage */
-  static final float[] POINTS = new float[6];
-
-  /** Reusable point for general internal usage */
-  static final float[] POINTS2 = new float[6];
-
-  /** Used to know the max texture size allowed to be rendered */
-  private static int mMaxTextureSize;
-
-  /** used to save bitmaps during state save and restore so not to reload them. */
-  static Pair<String, WeakReference<Bitmap>> mStateBitmap;
-
-  /**
-   * Rotate the given image by reading the Exif value of the image (uri).<br>
-   * If no rotation is required the image will not be rotated.<br>
-   * New bitmap is created and the old one is recycled.
-   */
-  static RotateBitmapResult rotateBitmapByExif(Bitmap bitmap, Context context, Uri uri) {
-    ExifInterface ei = null;
-    try {
-      InputStream is = context.getContentResolver().openInputStream(uri);
-      if (is != null) {
-        ei = new ExifInterface(is);
-        is.close();
-      }
-    } catch (Exception ignored) {
-    }
-    return ei != null ? rotateBitmapByExif(bitmap, ei) : new RotateBitmapResult(bitmap, 0);
-  }
-
-  /**
-   * Rotate the given image by given Exif value.<br>
-   * If no rotation is required the image will not be rotated.<br>
-   * New bitmap is created and the old one is recycled.
-   */
-  static RotateBitmapResult rotateBitmapByExif(Bitmap bitmap, ExifInterface exif) {
-    int degrees;
-    int orientation =
-        exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
-    switch (orientation) {
-      case ExifInterface.ORIENTATION_ROTATE_90:
-        degrees = 90;
-        break;
-      case ExifInterface.ORIENTATION_ROTATE_180:
-        degrees = 180;
-        break;
-      case ExifInterface.ORIENTATION_ROTATE_270:
-        degrees = 270;
-        break;
-      default:
-        degrees = 0;
-        break;
-    }
-    return new RotateBitmapResult(bitmap, degrees);
-  }
-
-  /** Decode bitmap from stream using sampling to get bitmap with the requested limit. */
-  static BitmapSampled decodeSampledBitmap(Context context, Uri uri, int reqWidth, int reqHeight) {
-
-    try {
-      ContentResolver resolver = context.getContentResolver();
-
-      // First decode with inJustDecodeBounds=true to check dimensions
-      BitmapFactory.Options options = decodeImageForOption(resolver, uri);
-
-      if(options.outWidth  == -1 && options.outHeight == -1)
-        throw new RuntimeException("File is not a picture");
-
-      // Calculate inSampleSize
-      options.inSampleSize =
-          Math.max(
-              calculateInSampleSizeByReqestedSize(
-                  options.outWidth, options.outHeight, reqWidth, reqHeight),
-              calculateInSampleSizeByMaxTextureSize(options.outWidth, options.outHeight));
-
-      // Decode bitmap with inSampleSize set
-      Bitmap bitmap = decodeImage(resolver, uri, options);
-
-      return new BitmapSampled(bitmap, options.inSampleSize);
-
-    } catch (Exception e) {
-      throw new RuntimeException(
-          "Failed to load sampled bitmap: " + uri + "\r\n" + e.getMessage(), e);
-    }
-  }
-
-  /**
-   * Crop image bitmap from given bitmap using the given points in the original bitmap and the given
-   * rotation.<br>
-   * if the rotation is not 0,90,180 or 270 degrees then we must first crop a larger area of the
-   * image that contains the requires rectangle, rotate and then crop again a sub rectangle.<br>
-   * If crop fails due to OOM we scale the cropping image by 0.5 every time it fails until it is
-   * small enough.
-   */
-  static BitmapSampled cropBitmapObjectHandleOOM(
-      Bitmap bitmap,
-      float[] points,
-      int degreesRotated,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY,
-      boolean flipHorizontally,
-      boolean flipVertically) {
-    int scale = 1;
-    while (true) {
-      try {
-        Bitmap cropBitmap =
-            cropBitmapObjectWithScale(
-                bitmap,
-                points,
-                degreesRotated,
-                fixAspectRatio,
-                aspectRatioX,
-                aspectRatioY,
-                1 / (float) scale,
-                flipHorizontally,
-                flipVertically);
-        return new BitmapSampled(cropBitmap, scale);
-      } catch (OutOfMemoryError e) {
-        scale *= 2;
-        if (scale > 8) {
-          throw e;
-        }
-      }
-    }
-  }
-
-  /**
-   * Crop image bitmap from given bitmap using the given points in the original bitmap and the given
-   * rotation.<br>
-   * if the rotation is not 0,90,180 or 270 degrees then we must first crop a larger area of the
-   * image that contains the requires rectangle, rotate and then crop again a sub rectangle.
-   *
-   * @param scale how much to scale the cropped image part, use 0.5 to lower the image by half (OOM
-   *     handling)
-   */
-  private static Bitmap cropBitmapObjectWithScale(
-      Bitmap bitmap,
-      float[] points,
-      int degreesRotated,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY,
-      float scale,
-      boolean flipHorizontally,
-      boolean flipVertically) {
-
-    // get the rectangle in original image that contains the required cropped area (larger for non
-    // rectangular crop)
-    Rect rect =
-        getRectFromPoints(
-            points,
-            bitmap.getWidth(),
-            bitmap.getHeight(),
-            fixAspectRatio,
-            aspectRatioX,
-            aspectRatioY);
-
-    // crop and rotate the cropped image in one operation
-    Matrix matrix = new Matrix();
-    matrix.setRotate(degreesRotated, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
-    matrix.postScale(flipHorizontally ? -scale : scale, flipVertically ? -scale : scale);
-    Bitmap result =
-        Bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height(), matrix, true);
-
-    if (result == bitmap) {
-      // corner case when all bitmap is selected, no worth optimizing for it
-      result = bitmap.copy(bitmap.getConfig(), false);
-    }
-
-    // rotating by 0, 90, 180 or 270 degrees doesn't require extra cropping
-    if (degreesRotated % 90 != 0) {
-
-      // extra crop because non rectangular crop cannot be done directly on the image without
-      // rotating first
-      result =
-          cropForRotatedImage(
-              result, points, rect, degreesRotated, fixAspectRatio, aspectRatioX, aspectRatioY);
-    }
-
-    return result;
-  }
-
-  /**
-   * Crop image bitmap from URI by decoding it with specific width and height to down-sample if
-   * required.<br>
-   * Additionally if OOM is thrown try to increase the sampling (2,4,8).
-   */
-  static BitmapSampled cropBitmap(
-      Context context,
-      Uri loadedImageUri,
-      float[] points,
-      int degreesRotated,
-      int orgWidth,
-      int orgHeight,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY,
-      int reqWidth,
-      int reqHeight,
-      boolean flipHorizontally,
-      boolean flipVertically) {
-    int sampleMulti = 1;
-    while (true) {
-      try {
-        // if successful, just return the resulting bitmap
-        return cropBitmap(
-            context,
-            loadedImageUri,
-            points,
-            degreesRotated,
-            orgWidth,
-            orgHeight,
-            fixAspectRatio,
-            aspectRatioX,
-            aspectRatioY,
-            reqWidth,
-            reqHeight,
-            flipHorizontally,
-            flipVertically,
-            sampleMulti);
-      } catch (OutOfMemoryError e) {
-        // if OOM try to increase the sampling to lower the memory usage
-        sampleMulti *= 2;
-        if (sampleMulti > 16) {
-          throw new RuntimeException(
-              "Failed to handle OOM by sampling ("
-                  + sampleMulti
-                  + "): "
-                  + loadedImageUri
-                  + "\r\n"
-                  + e.getMessage(),
-              e);
-        }
-      }
-    }
-  }
-
-  /** Get left value of the bounding rectangle of the given points. */
-  static float getRectLeft(float[] points) {
-    return Math.min(Math.min(Math.min(points[0], points[2]), points[4]), points[6]);
-  }
-
-  /** Get top value of the bounding rectangle of the given points. */
-  static float getRectTop(float[] points) {
-    return Math.min(Math.min(Math.min(points[1], points[3]), points[5]), points[7]);
-  }
-
-  /** Get right value of the bounding rectangle of the given points. */
-  static float getRectRight(float[] points) {
-    return Math.max(Math.max(Math.max(points[0], points[2]), points[4]), points[6]);
-  }
-
-  /** Get bottom value of the bounding rectangle of the given points. */
-  static float getRectBottom(float[] points) {
-    return Math.max(Math.max(Math.max(points[1], points[3]), points[5]), points[7]);
-  }
-
-  /** Get width of the bounding rectangle of the given points. */
-  static float getRectWidth(float[] points) {
-    return getRectRight(points) - getRectLeft(points);
-  }
-
-  /** Get height of the bounding rectangle of the given points. */
-  static float getRectHeight(float[] points) {
-    return getRectBottom(points) - getRectTop(points);
-  }
-
-  /** Get horizontal center value of the bounding rectangle of the given points. */
-  static float getRectCenterX(float[] points) {
-    return (getRectRight(points) + getRectLeft(points)) / 2f;
-  }
-
-  /** Get vertical center value of the bounding rectangle of the given points. */
-  static float getRectCenterY(float[] points) {
-    return (getRectBottom(points) + getRectTop(points)) / 2f;
-  }
-
-  /**
-   * Get a rectangle for the given 4 points (x0,y0,x1,y1,x2,y2,x3,y3) by finding the min/max 2
-   * points that contains the given 4 points and is a straight rectangle.
-   */
-  static Rect getRectFromPoints(
-      float[] points,
-      int imageWidth,
-      int imageHeight,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY) {
-    int left = Math.round(Math.max(0, getRectLeft(points)));
-    int top = Math.round(Math.max(0, getRectTop(points)));
-    int right = Math.round(Math.min(imageWidth, getRectRight(points)));
-    int bottom = Math.round(Math.min(imageHeight, getRectBottom(points)));
-
-    Rect rect = new Rect(left, top, right, bottom);
-    if (fixAspectRatio) {
-      fixRectForAspectRatio(rect, aspectRatioX, aspectRatioY);
-    }
-
-    return rect;
-  }
-
-  /**
-   * Fix the given rectangle if it doesn't confirm to aspect ration rule.<br>
-   * Make sure that width and height are equal if 1:1 fixed aspect ratio is requested.
-   */
-  private static void fixRectForAspectRatio(Rect rect, int aspectRatioX, int aspectRatioY) {
-    if (aspectRatioX == aspectRatioY && rect.width() != rect.height()) {
-      if (rect.height() > rect.width()) {
-        rect.bottom -= rect.height() - rect.width();
-      } else {
-        rect.right -= rect.width() - rect.height();
-      }
-    }
-  }
-
-  /**
-   * Write given bitmap to a temp file. If file already exists no-op as we already saved the file in
-   * this session. Uses JPEG 95% compression.
-   *
-   * @param uri the uri to write the bitmap to, if null
-   * @return the uri where the image was saved in, either the given uri or new pointing to temp
-   *     file.
-   */
-  static Uri writeTempStateStoreBitmap(Context context, Bitmap bitmap, Uri uri) {
-    try {
-      boolean needSave = true;
-      if (uri == null) {
-        uri =
-            Uri.fromFile(
-                File.createTempFile("aic_state_store_temp", ".jpg", context.getCacheDir()));
-      } else if (new File(uri.getPath()).exists()) {
-        needSave = false;
-      }
-      if (needSave) {
-        writeBitmapToUri(context, bitmap, uri, Bitmap.CompressFormat.JPEG, 95);
-      }
-      return uri;
-    } catch (Exception e) {
-      Log.w("AIC", "Failed to write bitmap to temp file for image-cropper save instance state", e);
-      return null;
-    }
-  }
-
-  /** Write the given bitmap to the given uri using the given compression. */
-  static void writeBitmapToUri(
-      Context context,
-      Bitmap bitmap,
-      Uri uri,
-      Bitmap.CompressFormat compressFormat,
-      int compressQuality)
-      throws FileNotFoundException {
-    OutputStream outputStream = null;
-    try {
-      outputStream = context.getContentResolver().openOutputStream(uri);
-      bitmap.compress(compressFormat, compressQuality, outputStream);
-    } finally {
-      closeSafe(outputStream);
-    }
-  }
-
-  /** Resize the given bitmap to the given width/height by the given option.<br> */
-  static Bitmap resizeBitmap(
-      Bitmap bitmap, int reqWidth, int reqHeight, CropImageView.RequestSizeOptions options) {
-    try {
-      if (reqWidth > 0
-          && reqHeight > 0
-          && (options == CropImageView.RequestSizeOptions.RESIZE_FIT
-              || options == CropImageView.RequestSizeOptions.RESIZE_INSIDE
-              || options == CropImageView.RequestSizeOptions.RESIZE_EXACT)) {
-
-        Bitmap resized = null;
-        if (options == CropImageView.RequestSizeOptions.RESIZE_EXACT) {
-          resized = Bitmap.createScaledBitmap(bitmap, reqWidth, reqHeight, false);
-        } else {
-          int width = bitmap.getWidth();
-          int height = bitmap.getHeight();
-          float scale = Math.max(width / (float) reqWidth, height / (float) reqHeight);
-          if (scale > 1 || options == CropImageView.RequestSizeOptions.RESIZE_FIT) {
-            resized =
-                Bitmap.createScaledBitmap(
-                    bitmap, (int) (width / scale), (int) (height / scale), false);
-          }
-        }
-        if (resized != null) {
-          if (resized != bitmap) {
-            bitmap.recycle();
-          }
-          return resized;
-        }
-      }
-    } catch (Exception e) {
-      Log.w("AIC", "Failed to resize cropped image, return bitmap before resize", e);
-    }
-    return bitmap;
-  }
-
-  // region: Private methods
-
-  /**
-   * Crop image bitmap from URI by decoding it with specific width and height to down-sample if
-   * required.
-   *
-   * @param orgWidth used to get rectangle from points (handle edge cases to limit rectangle)
-   * @param orgHeight used to get rectangle from points (handle edge cases to limit rectangle)
-   * @param sampleMulti used to increase the sampling of the image to handle memory issues.
-   */
-  private static BitmapSampled cropBitmap(
-      Context context,
-      Uri loadedImageUri,
-      float[] points,
-      int degreesRotated,
-      int orgWidth,
-      int orgHeight,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY,
-      int reqWidth,
-      int reqHeight,
-      boolean flipHorizontally,
-      boolean flipVertically,
-      int sampleMulti) {
-
-    // get the rectangle in original image that contains the required cropped area (larger for non
-    // rectangular crop)
-    Rect rect =
-        getRectFromPoints(points, orgWidth, orgHeight, fixAspectRatio, aspectRatioX, aspectRatioY);
-
-    int width = reqWidth > 0 ? reqWidth : rect.width();
-    int height = reqHeight > 0 ? reqHeight : rect.height();
-
-    Bitmap result = null;
-    int sampleSize = 1;
-    try {
-      // decode only the required image from URI, optionally sub-sampling if reqWidth/reqHeight is
-      // given.
-      BitmapSampled bitmapSampled =
-          decodeSampledBitmapRegion(context, loadedImageUri, rect, width, height, sampleMulti);
-      result = bitmapSampled.bitmap;
-      sampleSize = bitmapSampled.sampleSize;
-    } catch (Exception ignored) {
-    }
-
-    if (result != null) {
-      try {
-        // rotate the decoded region by the required amount
-        result = rotateAndFlipBitmapInt(result, degreesRotated, flipHorizontally, flipVertically);
-
-        // rotating by 0, 90, 180 or 270 degrees doesn't require extra cropping
-        if (degreesRotated % 90 != 0) {
-
-          // extra crop because non rectangular crop cannot be done directly on the image without
-          // rotating first
-          result =
-              cropForRotatedImage(
-                  result, points, rect, degreesRotated, fixAspectRatio, aspectRatioX, aspectRatioY);
-        }
-      } catch (OutOfMemoryError e) {
-        if (result != null) {
-          result.recycle();
-        }
-        throw e;
-      }
-      return new BitmapSampled(result, sampleSize);
-    } else {
-      // failed to decode region, may be skia issue, try full decode and then crop
-      return cropBitmap(
-          context,
-          loadedImageUri,
-          points,
-          degreesRotated,
-          fixAspectRatio,
-          aspectRatioX,
-          aspectRatioY,
-          sampleMulti,
-          rect,
-          width,
-          height,
-          flipHorizontally,
-          flipVertically);
-    }
-  }
-
-  /**
-   * Crop bitmap by fully loading the original and then cropping it, fallback in case cropping
-   * region failed.
-   */
-  private static BitmapSampled cropBitmap(
-      Context context,
-      Uri loadedImageUri,
-      float[] points,
-      int degreesRotated,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY,
-      int sampleMulti,
-      Rect rect,
-      int width,
-      int height,
-      boolean flipHorizontally,
-      boolean flipVertically) {
-    Bitmap result = null;
-    int sampleSize;
-    try {
-      BitmapFactory.Options options = new BitmapFactory.Options();
-      options.inSampleSize =
-          sampleSize =
-              sampleMulti
-                  * calculateInSampleSizeByReqestedSize(rect.width(), rect.height(), width, height);
-
-      Bitmap fullBitmap = decodeImage(context.getContentResolver(), loadedImageUri, options);
-      if (fullBitmap != null) {
-        try {
-          // adjust crop points by the sampling because the image is smaller
-          float[] points2 = new float[points.length];
-          System.arraycopy(points, 0, points2, 0, points.length);
-          for (int i = 0; i < points2.length; i++) {
-            points2[i] = points2[i] / options.inSampleSize;
-          }
-
-          result =
-              cropBitmapObjectWithScale(
-                  fullBitmap,
-                  points2,
-                  degreesRotated,
-                  fixAspectRatio,
-                  aspectRatioX,
-                  aspectRatioY,
-                  1,
-                  flipHorizontally,
-                  flipVertically);
-        } finally {
-          if (result != fullBitmap) {
-            fullBitmap.recycle();
-          }
-        }
-      }
-    } catch (OutOfMemoryError e) {
-      if (result != null) {
-        result.recycle();
-      }
-      throw e;
-    } catch (Exception e) {
-      throw new RuntimeException(
-          "Failed to load sampled bitmap: " + loadedImageUri + "\r\n" + e.getMessage(), e);
-    }
-    return new BitmapSampled(result, sampleSize);
-  }
-
-  /** Decode image from uri using "inJustDecodeBounds" to get the image dimensions. */
-  private static BitmapFactory.Options decodeImageForOption(ContentResolver resolver, Uri uri)
-      throws FileNotFoundException {
-    InputStream stream = null;
-    try {
-      stream = resolver.openInputStream(uri);
-      BitmapFactory.Options options = new BitmapFactory.Options();
-      options.inJustDecodeBounds = true;
-      BitmapFactory.decodeStream(stream, EMPTY_RECT, options);
-      options.inJustDecodeBounds = false;
-      return options;
-    } finally {
-      closeSafe(stream);
-    }
-  }
-
-  /**
-   * Decode image from uri using given "inSampleSize", but if failed due to out-of-memory then raise
-   * the inSampleSize until success.
-   */
-  private static Bitmap decodeImage(
-      ContentResolver resolver, Uri uri, BitmapFactory.Options options)
-      throws FileNotFoundException {
-    do {
-      InputStream stream = null;
-      try {
-        stream = resolver.openInputStream(uri);
-        return BitmapFactory.decodeStream(stream, EMPTY_RECT, options);
-      } catch (OutOfMemoryError e) {
-        options.inSampleSize *= 2;
-      } finally {
-        closeSafe(stream);
-      }
-    } while (options.inSampleSize <= 512);
-    throw new RuntimeException("Failed to decode image: " + uri);
-  }
-
-  /**
-   * Decode specific rectangle bitmap from stream using sampling to get bitmap with the requested
-   * limit.
-   *
-   * @param sampleMulti used to increase the sampling of the image to handle memory issues.
-   */
-  private static BitmapSampled decodeSampledBitmapRegion(
-      Context context, Uri uri, Rect rect, int reqWidth, int reqHeight, int sampleMulti) {
-    InputStream stream = null;
-    BitmapRegionDecoder decoder = null;
-    try {
-      BitmapFactory.Options options = new BitmapFactory.Options();
-      options.inSampleSize =
-          sampleMulti
-              * calculateInSampleSizeByReqestedSize(
-                  rect.width(), rect.height(), reqWidth, reqHeight);
-
-      stream = context.getContentResolver().openInputStream(uri);
-      decoder = BitmapRegionDecoder.newInstance(stream, false);
-      do {
-        try {
-          return new BitmapSampled(decoder.decodeRegion(rect, options), options.inSampleSize);
-        } catch (OutOfMemoryError e) {
-          options.inSampleSize *= 2;
-        }
-      } while (options.inSampleSize <= 512);
-    } catch (Exception e) {
-      throw new RuntimeException(
-          "Failed to load sampled bitmap: " + uri + "\r\n" + e.getMessage(), e);
-    } finally {
-      closeSafe(stream);
-      if (decoder != null) {
-        decoder.recycle();
-      }
-    }
-    return new BitmapSampled(null, 1);
-  }
-
-  /**
-   * Special crop of bitmap rotated by not stright angle, in this case the original crop bitmap
-   * contains parts beyond the required crop area, this method crops the already cropped and rotated
-   * bitmap to the final rectangle.<br>
-   * Note: rotating by 0, 90, 180 or 270 degrees doesn't require extra cropping.
-   */
-  private static Bitmap cropForRotatedImage(
-      Bitmap bitmap,
-      float[] points,
-      Rect rect,
-      int degreesRotated,
-      boolean fixAspectRatio,
-      int aspectRatioX,
-      int aspectRatioY) {
-    if (degreesRotated % 90 != 0) {
-
-      int adjLeft = 0, adjTop = 0, width = 0, height = 0;
-      double rads = Math.toRadians(degreesRotated);
-      int compareTo =
-          degreesRotated < 90 || (degreesRotated > 180 && degreesRotated < 270)
-              ? rect.left
-              : rect.right;
-      for (int i = 0; i < points.length; i += 2) {
-        if (points[i] >= compareTo - 1 && points[i] <= compareTo + 1) {
-          adjLeft = (int) Math.abs(Math.sin(rads) * (rect.bottom - points[i + 1]));
-          adjTop = (int) Math.abs(Math.cos(rads) * (points[i + 1] - rect.top));
-          width = (int) Math.abs((points[i + 1] - rect.top) / Math.sin(rads));
-          height = (int) Math.abs((rect.bottom - points[i + 1]) / Math.cos(rads));
-          break;
-        }
-      }
-
-      rect.set(adjLeft, adjTop, adjLeft + width, adjTop + height);
-      if (fixAspectRatio) {
-        fixRectForAspectRatio(rect, aspectRatioX, aspectRatioY);
-      }
-
-      Bitmap bitmapTmp = bitmap;
-      bitmap = Bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height());
-      if (bitmapTmp != bitmap) {
-        bitmapTmp.recycle();
-      }
-    }
-    return bitmap;
-  }
-
-  /**
-   * Calculate the largest inSampleSize value that is a power of 2 and keeps both height and width
-   * larger than the requested height and width.
-   */
-  private static int calculateInSampleSizeByReqestedSize(
-      int width, int height, int reqWidth, int reqHeight) {
-    int inSampleSize = 1;
-    if (height > reqHeight || width > reqWidth) {
-      while ((height / 2 / inSampleSize) > reqHeight && (width / 2 / inSampleSize) > reqWidth) {
-        inSampleSize *= 2;
-      }
-    }
-    return inSampleSize;
-  }
-
-  /**
-   * Calculate the largest inSampleSize value that is a power of 2 and keeps both height and width
-   * smaller than max texture size allowed for the device.
-   */
-  private static int calculateInSampleSizeByMaxTextureSize(int width, int height) {
-    int inSampleSize = 1;
-    if (mMaxTextureSize == 0) {
-      mMaxTextureSize = getMaxTextureSize();
-    }
-    if (mMaxTextureSize > 0) {
-      while ((height / inSampleSize) > mMaxTextureSize
-          || (width / inSampleSize) > mMaxTextureSize) {
-        inSampleSize *= 2;
-      }
-    }
-    return inSampleSize;
-  }
-
-  /**
-   * Rotate the given bitmap by the given degrees.<br>
-   * New bitmap is created and the old one is recycled.
-   */
-  private static Bitmap rotateAndFlipBitmapInt(
-      Bitmap bitmap, int degrees, boolean flipHorizontally, boolean flipVertically) {
-    if (degrees > 0 || flipHorizontally || flipVertically) {
-      Matrix matrix = new Matrix();
-      matrix.setRotate(degrees);
-      matrix.postScale(flipHorizontally ? -1 : 1, flipVertically ? -1 : 1);
-      Bitmap newBitmap =
-          Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
-      if (newBitmap != bitmap) {
-        bitmap.recycle();
-      }
-      return newBitmap;
-    } else {
-      return bitmap;
-    }
-  }
-
-  /**
-   * Get the max size of bitmap allowed to be rendered on the device.<br>
-   * http://stackoverflow.com/questions/7428996/hw-accelerated-activity-how-to-get-opengl-texture-size-limit.
-   */
-  private static int getMaxTextureSize() {
-    // Safe minimum default size
-    final int IMAGE_MAX_BITMAP_DIMENSION = 2048;
-
-    try {
-      // Get EGL Display
-      EGL10 egl = (EGL10) EGLContext.getEGL();
-      EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-
-      // Initialise
-      int[] version = new int[2];
-      egl.eglInitialize(display, version);
-
-      // Query total number of configurations
-      int[] totalConfigurations = new int[1];
-      egl.eglGetConfigs(display, null, 0, totalConfigurations);
-
-      // Query actual list configurations
-      EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]];
-      egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations);
-
-      int[] textureSize = new int[1];
-      int maximumTextureSize = 0;
-
-      // Iterate through all the configurations to located the maximum texture size
-      for (int i = 0; i < totalConfigurations[0]; i++) {
-        // Only need to check for width since opengl textures are always squared
-        egl.eglGetConfigAttrib(
-            display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize);
-
-        // Keep track of the maximum texture size
-        if (maximumTextureSize < textureSize[0]) {
-          maximumTextureSize = textureSize[0];
-        }
-      }
-
-      // Release
-      egl.eglTerminate(display);
-
-      // Return largest texture size found, or default
-      return Math.max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION);
-    } catch (Exception e) {
-      return IMAGE_MAX_BITMAP_DIMENSION;
-    }
-  }
-
-  /**
-   * Close the given closeable object (Stream) in a safe way: check if it is null and catch-log
-   * exception thrown.
-   *
-   * @param closeable the closable object to close
-   */
-  private static void closeSafe(Closeable closeable) {
-    if (closeable != null) {
-      try {
-        closeable.close();
-      } catch (IOException ignored) {
-      }
-    }
-  }
-  // endregion
-
-  // region: Inner class: BitmapSampled
-
-  /** Holds bitmap instance and the sample size that the bitmap was loaded/cropped with. */
-  static final class BitmapSampled {
-
-    /** The bitmap instance */
-    public final Bitmap bitmap;
-
-    /** The sample size used to lower the size of the bitmap (1,2,4,8,...) */
-    final int sampleSize;
-
-    BitmapSampled(Bitmap bitmap, int sampleSize) {
-      this.bitmap = bitmap;
-      this.sampleSize = sampleSize;
-    }
-  }
-  // endregion
-
-  // region: Inner class: RotateBitmapResult
-
-  /** The result of {@link #rotateBitmapByExif(Bitmap, ExifInterface)}. */
-  static final class RotateBitmapResult {
-
-    /** The loaded bitmap */
-    public final Bitmap bitmap;
-
-    /** The degrees the image was rotated */
-    final int degrees;
-
-    RotateBitmapResult(Bitmap bitmap, int degrees) {
-      this.bitmap = bitmap;
-      this.degrees = degrees;
-    }
-  }
-  // endregion
-}

Plik diff jest za duży
+ 0 - 1020
app/src/main/java/com/miekir/ocr/view/cropper/CropImage.java


+ 0 - 352
app/src/main/java/com/miekir/ocr/view/cropper/CropImageActivity.java

@@ -1,352 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth,
-// inexhaustible as the great rivers.
-// When they come to an end,
-// they begin again,
-// like the days and months;
-// they die and are reborn,
-// like the four seasons."
-//
-// - Sun Tsu,
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.Manifest;
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.core.content.ContextCompat;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AppCompatActivity;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.Toast;
-
-import com.miekir.ocr.R;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Built-in activity for image cropping.<br>
- * Use {@link CropImage#activity(Uri)} to create a builder to start this activity.
- */
-public class CropImageActivity extends AppCompatActivity
-    implements CropImageView.OnSetImageUriCompleteListener,
-        CropImageView.OnCropImageCompleteListener {
-
-  /** The crop image view library widget used in the activity */
-  private CropImageView mCropImageView;
-
-  /** Persist URI image to crop URI if specific permissions are required */
-  private Uri mCropImageUri;
-
-  /** the options that were set for the crop image */
-  private CropImageOptions mOptions;
-
-  @Override
-  @SuppressLint("NewApi")
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    setContentView(R.layout.crop_image_activity);
-
-    mCropImageView = findViewById(R.id.cropImageView);
-
-    Bundle bundle = getIntent().getBundleExtra(CropImage.CROP_IMAGE_EXTRA_BUNDLE);
-    mCropImageUri = bundle.getParcelable(CropImage.CROP_IMAGE_EXTRA_SOURCE);
-    mOptions = bundle.getParcelable(CropImage.CROP_IMAGE_EXTRA_OPTIONS);
-
-    if (savedInstanceState == null) {
-      if (mCropImageUri == null || mCropImageUri.equals(Uri.EMPTY)) {
-        if (CropImage.isExplicitCameraPermissionRequired(this)) {
-          // request permissions and handle the result in onRequestPermissionsResult()
-          requestPermissions(
-              new String[] {Manifest.permission.CAMERA},
-              CropImage.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
-        } else {
-          CropImage.startPickImageActivity(this);
-        }
-      } else if (CropImage.isReadExternalStoragePermissionsRequired(this, mCropImageUri)) {
-        // request permissions and handle the result in onRequestPermissionsResult()
-        requestPermissions(
-            new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},
-            CropImage.PICK_IMAGE_PERMISSIONS_REQUEST_CODE);
-      } else {
-        // no permissions required or already grunted, can start crop image activity
-        mCropImageView.setImageUriAsync(mCropImageUri);
-      }
-    }
-
-    ActionBar actionBar = getSupportActionBar();
-    if (actionBar != null) {
-      CharSequence title = mOptions != null &&
-          mOptions.activityTitle != null && mOptions.activityTitle.length() > 0
-              ? mOptions.activityTitle
-              : getResources().getString(R.string.crop_image_activity_title);
-      actionBar.setTitle(title);
-      actionBar.setDisplayHomeAsUpEnabled(true);
-    }
-  }
-
-  @Override
-  protected void onStart() {
-    super.onStart();
-    mCropImageView.setOnSetImageUriCompleteListener(this);
-    mCropImageView.setOnCropImageCompleteListener(this);
-  }
-
-  @Override
-  protected void onStop() {
-    super.onStop();
-    mCropImageView.setOnSetImageUriCompleteListener(null);
-    mCropImageView.setOnCropImageCompleteListener(null);
-  }
-
-  @Override
-  public boolean onCreateOptionsMenu(Menu menu) {
-    getMenuInflater().inflate(R.menu.crop_image_menu, menu);
-
-    if (!mOptions.allowRotation) {
-      menu.removeItem(R.id.crop_image_menu_rotate_left);
-      menu.removeItem(R.id.crop_image_menu_rotate_right);
-    } else if (mOptions.allowCounterRotation) {
-      menu.findItem(R.id.crop_image_menu_rotate_left).setVisible(true);
-    }
-
-    if (!mOptions.allowFlipping) {
-      menu.removeItem(R.id.crop_image_menu_flip);
-    }
-
-    if (mOptions.cropMenuCropButtonTitle != null) {
-      menu.findItem(R.id.crop_image_menu_crop).setTitle(mOptions.cropMenuCropButtonTitle);
-    }
-
-    Drawable cropIcon = null;
-    try {
-      if (mOptions.cropMenuCropButtonIcon != 0) {
-        cropIcon = ContextCompat.getDrawable(this, mOptions.cropMenuCropButtonIcon);
-        menu.findItem(R.id.crop_image_menu_crop).setIcon(cropIcon);
-      }
-    } catch (Exception e) {
-      Log.w("AIC", "Failed to read menu crop drawable", e);
-    }
-
-    if (mOptions.activityMenuIconColor != 0) {
-      updateMenuItemIconColor(
-          menu, R.id.crop_image_menu_rotate_left, mOptions.activityMenuIconColor);
-      updateMenuItemIconColor(
-          menu, R.id.crop_image_menu_rotate_right, mOptions.activityMenuIconColor);
-      updateMenuItemIconColor(menu, R.id.crop_image_menu_flip, mOptions.activityMenuIconColor);
-      if (cropIcon != null) {
-        updateMenuItemIconColor(menu, R.id.crop_image_menu_crop, mOptions.activityMenuIconColor);
-      }
-    }
-    return true;
-  }
-
-  @Override
-  public boolean onOptionsItemSelected(MenuItem item) {
-    if (item.getItemId() == R.id.crop_image_menu_crop) {
-      cropImage();
-      return true;
-    }
-    if (item.getItemId() == R.id.crop_image_menu_rotate_left) {
-      rotateImage(-mOptions.rotationDegrees);
-      return true;
-    }
-    if (item.getItemId() == R.id.crop_image_menu_rotate_right) {
-      rotateImage(mOptions.rotationDegrees);
-      return true;
-    }
-    if (item.getItemId() == R.id.crop_image_menu_flip_horizontally) {
-      mCropImageView.flipImageHorizontally();
-      return true;
-    }
-    if (item.getItemId() == R.id.crop_image_menu_flip_vertically) {
-      mCropImageView.flipImageVertically();
-      return true;
-    }
-    if (item.getItemId() == android.R.id.home) {
-      setResultCancel();
-      return true;
-    }
-    return super.onOptionsItemSelected(item);
-  }
-
-  @Override
-  public void onBackPressed() {
-    super.onBackPressed();
-    setResultCancel();
-  }
-
-  @Override
-  @SuppressLint("NewApi")
-  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-
-    // handle result of pick image chooser
-    if (requestCode == CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE) {
-      if (resultCode == Activity.RESULT_CANCELED) {
-        // User cancelled the picker. We don't have anything to crop
-        setResultCancel();
-      }
-
-      if (resultCode == Activity.RESULT_OK) {
-        mCropImageUri = CropImage.getPickImageResultUri(this, data);
-
-        // For API >= 23 we need to check specifically that we have permissions to read external
-        // storage.
-        if (CropImage.isReadExternalStoragePermissionsRequired(this, mCropImageUri)) {
-          // request permissions and handle the result in onRequestPermissionsResult()
-          requestPermissions(
-              new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},
-              CropImage.PICK_IMAGE_PERMISSIONS_REQUEST_CODE);
-        } else {
-          // no permissions required or already grunted, can start crop image activity
-          mCropImageView.setImageUriAsync(mCropImageUri);
-        }
-      }
-    }
-  }
-
-  @Override
-  public void onRequestPermissionsResult(
-      int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
-    if (requestCode == CropImage.PICK_IMAGE_PERMISSIONS_REQUEST_CODE) {
-      if (mCropImageUri != null
-          && grantResults.length > 0
-          && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-        // required permissions granted, start crop image activity
-        mCropImageView.setImageUriAsync(mCropImageUri);
-      } else {
-        Toast.makeText(this, R.string.crop_image_activity_no_permissions, Toast.LENGTH_LONG).show();
-        setResultCancel();
-      }
-    }
-
-    if (requestCode == CropImage.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE) {
-      // Irrespective of whether camera permission was given or not, we show the picker
-      // The picker will not add the camera intent if permission is not available
-      CropImage.startPickImageActivity(this);
-    }
-  }
-
-  @Override
-  public void onSetImageUriComplete(CropImageView view, Uri uri, Exception error) {
-    if (error == null) {
-      if (mOptions.initialCropWindowRectangle != null) {
-        mCropImageView.setCropRect(mOptions.initialCropWindowRectangle);
-      }
-      if (mOptions.initialRotation > -1) {
-        mCropImageView.setRotatedDegrees(mOptions.initialRotation);
-      }
-    } else {
-      setResult(null, error, 1);
-    }
-  }
-
-  @Override
-  public void onCropImageComplete(CropImageView view, CropImageView.CropResult result) {
-    setResult(result.getUri(), result.getError(), result.getSampleSize());
-  }
-
-  // region: Private methods
-
-  /** Execute crop image and save the result tou output uri. */
-  protected void cropImage() {
-    if (mOptions.noOutputImage) {
-      setResult(null, null, 1);
-    } else {
-      Uri outputUri = getOutputUri();
-      mCropImageView.saveCroppedImageAsync(
-          outputUri,
-          mOptions.outputCompressFormat,
-          mOptions.outputCompressQuality,
-          mOptions.outputRequestWidth,
-          mOptions.outputRequestHeight,
-          mOptions.outputRequestSizeOptions);
-    }
-  }
-
-  /** Rotate the image in the crop image view. */
-  protected void rotateImage(int degrees) {
-    mCropImageView.rotateImage(degrees);
-  }
-
-  /**
-   * Get Android uri to save the cropped image into.<br>
-   * Use the given in options or create a temp file.
-   */
-  protected Uri getOutputUri() {
-    Uri outputUri = mOptions.outputUri;
-    if (outputUri == null || outputUri.equals(Uri.EMPTY)) {
-      try {
-        String ext =
-            mOptions.outputCompressFormat == Bitmap.CompressFormat.JPEG
-                ? ".jpg"
-                : mOptions.outputCompressFormat == Bitmap.CompressFormat.PNG ? ".png" : ".webp";
-        outputUri = Uri.fromFile(File.createTempFile("cropped", ext, getCacheDir()));
-      } catch (IOException e) {
-        throw new RuntimeException("Failed to create temp file for output image", e);
-      }
-    }
-    return outputUri;
-  }
-
-  /** Result with cropped image data or error if failed. */
-  protected void setResult(Uri uri, Exception error, int sampleSize) {
-    int resultCode = error == null ? RESULT_OK : CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE;
-    setResult(resultCode, getResultIntent(uri, error, sampleSize));
-    finish();
-  }
-
-  /** Cancel of cropping activity. */
-  protected void setResultCancel() {
-    setResult(RESULT_CANCELED);
-    finish();
-  }
-
-  /** Get intent instance to be used for the result of this activity. */
-  protected Intent getResultIntent(Uri uri, Exception error, int sampleSize) {
-    CropImage.ActivityResult result =
-        new CropImage.ActivityResult(
-            mCropImageView.getImageUri(),
-            uri,
-            error,
-            mCropImageView.getCropPoints(),
-            mCropImageView.getCropRect(),
-            mCropImageView.getRotatedDegrees(),
-            mCropImageView.getWholeImageRect(),
-            sampleSize);
-    Intent intent = new Intent();
-    intent.putExtras(getIntent());
-    intent.putExtra(CropImage.CROP_IMAGE_EXTRA_RESULT, result);
-    return intent;
-  }
-
-  /** Update the color of a specific menu item to the given color. */
-  private void updateMenuItemIconColor(Menu menu, int itemId, int color) {
-    MenuItem menuItem = menu.findItem(itemId);
-    if (menuItem != null) {
-      Drawable menuItemIcon = menuItem.getIcon();
-      if (menuItemIcon != null) {
-        try {
-          menuItemIcon.mutate();
-          menuItemIcon.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
-          menuItem.setIcon(menuItemIcon);
-        } catch (Exception e) {
-          Log.w("AIC", "Failed to update menu item color", e);
-        }
-      }
-    }
-  }
-  // endregion
-}

+ 0 - 123
app/src/main/java/com/miekir/ocr/view/cropper/CropImageAnimation.java

@@ -1,123 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth,
-// inexhaustible as the great rivers.
-// When they come to an end,
-// they begin again,
-// like the days and months;
-// they die and are reborn,
-// like the four seasons."
-//
-// - Sun Tsu,
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.graphics.Matrix;
-import android.graphics.RectF;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.Animation;
-import android.view.animation.Transformation;
-import android.widget.ImageView;
-
-/**
- * Animation to handle smooth cropping image matrix transformation change, specifically for
- * zoom-in/out.
- */
-final class CropImageAnimation extends Animation implements Animation.AnimationListener {
-
-  // region: Fields and Consts
-
-  private final ImageView mImageView;
-
-  private final CropOverlayView mCropOverlayView;
-
-  private final float[] mStartBoundPoints = new float[8];
-
-  private final float[] mEndBoundPoints = new float[8];
-
-  private final RectF mStartCropWindowRect = new RectF();
-
-  private final RectF mEndCropWindowRect = new RectF();
-
-  private final float[] mStartImageMatrix = new float[9];
-
-  private final float[] mEndImageMatrix = new float[9];
-
-  private final RectF mAnimRect = new RectF();
-
-  private final float[] mAnimPoints = new float[8];
-
-  private final float[] mAnimMatrix = new float[9];
-  // endregion
-
-  public CropImageAnimation(ImageView cropImageView, CropOverlayView cropOverlayView) {
-    mImageView = cropImageView;
-    mCropOverlayView = cropOverlayView;
-
-    setDuration(300);
-    setFillAfter(true);
-    setInterpolator(new AccelerateDecelerateInterpolator());
-    setAnimationListener(this);
-  }
-
-  public void setStartState(float[] boundPoints, Matrix imageMatrix) {
-    reset();
-    System.arraycopy(boundPoints, 0, mStartBoundPoints, 0, 8);
-    mStartCropWindowRect.set(mCropOverlayView.getCropWindowRect());
-    imageMatrix.getValues(mStartImageMatrix);
-  }
-
-  public void setEndState(float[] boundPoints, Matrix imageMatrix) {
-    System.arraycopy(boundPoints, 0, mEndBoundPoints, 0, 8);
-    mEndCropWindowRect.set(mCropOverlayView.getCropWindowRect());
-    imageMatrix.getValues(mEndImageMatrix);
-  }
-
-  @Override
-  protected void applyTransformation(float interpolatedTime, Transformation t) {
-
-    mAnimRect.left =
-        mStartCropWindowRect.left
-            + (mEndCropWindowRect.left - mStartCropWindowRect.left) * interpolatedTime;
-    mAnimRect.top =
-        mStartCropWindowRect.top
-            + (mEndCropWindowRect.top - mStartCropWindowRect.top) * interpolatedTime;
-    mAnimRect.right =
-        mStartCropWindowRect.right
-            + (mEndCropWindowRect.right - mStartCropWindowRect.right) * interpolatedTime;
-    mAnimRect.bottom =
-        mStartCropWindowRect.bottom
-            + (mEndCropWindowRect.bottom - mStartCropWindowRect.bottom) * interpolatedTime;
-    mCropOverlayView.setCropWindowRect(mAnimRect);
-
-    for (int i = 0; i < mAnimPoints.length; i++) {
-      mAnimPoints[i] =
-          mStartBoundPoints[i] + (mEndBoundPoints[i] - mStartBoundPoints[i]) * interpolatedTime;
-    }
-
-    //mCropOverlayView.setBounds(mAnimPoints, SizeTool.SCREEN_WIDTH, SizeTool.SCREEN_HEIGHT);
-    mCropOverlayView.setBounds(mAnimPoints, mImageView.getWidth(), mImageView.getHeight());
-
-    for (int i = 0; i < mAnimMatrix.length; i++) {
-      mAnimMatrix[i] =
-          mStartImageMatrix[i] + (mEndImageMatrix[i] - mStartImageMatrix[i]) * interpolatedTime;
-    }
-    Matrix m = mImageView.getImageMatrix();
-    m.setValues(mAnimMatrix);
-    mImageView.setImageMatrix(m);
-
-    mImageView.invalidate();
-    mCropOverlayView.invalidate();
-  }
-
-  @Override
-  public void onAnimationStart(Animation animation) {}
-
-  @Override
-  public void onAnimationEnd(Animation animation) {
-    mImageView.clearAnimation();
-  }
-
-  @Override
-  public void onAnimationRepeat(Animation animation) {}
-}

+ 0 - 471
app/src/main/java/com/miekir/ocr/view/cropper/CropImageOptions.java

@@ -1,471 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth;
-// inexhaustible as the great rivers.
-// When they come to an end;
-// they begin again;
-// like the days and months;
-// they die and are reborn;
-// like the four seasons."
-//
-// - Sun Tsu;
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-
-/**
- * All the possible options that can be set to customize crop image.<br>
- * Initialized with default values.
- */
-public class CropImageOptions implements Parcelable {
-
-  public static final Creator<CropImageOptions> CREATOR =
-      new Creator<CropImageOptions>() {
-        @Override
-        public CropImageOptions createFromParcel(Parcel in) {
-          return new CropImageOptions(in);
-        }
-
-        @Override
-        public CropImageOptions[] newArray(int size) {
-          return new CropImageOptions[size];
-        }
-      };
-
-  /** The shape of the cropping window. */
-  public CropImageView.CropShape cropShape;
-
-  /**
-   * An edge of the crop window will snap to the corresponding edge of a specified bounding box when
-   * the crop window edge is less than or equal to this distance (in pixels) away from the bounding
-   * box edge. (in pixels)
-   */
-  public float snapRadius;
-
-  /**
-   * The radius of the touchable area around the handle. (in pixels)<br>
-   * We are basing this value off of the recommended 48dp Rhythm.<br>
-   * See: http://developer.android.com/design/style/metrics-grids.html#48dp-rhythm
-   */
-  public float touchRadius;
-
-  /** whether the guidelines should be on, off, or only showing when resizing. */
-  public CropImageView.Guidelines guidelines;
-
-  /** The initial scale type of the image in the crop image view */
-  public CropImageView.ScaleType scaleType;
-
-  /**
-   * if to show crop overlay UI what contains the crop window UI surrounded by background over the
-   * cropping image.<br>
-   * default: true, may disable for animation or frame transition.
-   */
-  public boolean showCropOverlay;
-
-  /**
-   * if to show progress bar when image async loading/cropping is in progress.<br>
-   * default: true, disable to provide custom progress bar UI.
-   */
-  public boolean showProgressBar;
-
-  /**
-   * if auto-zoom functionality is enabled.<br>
-   * default: true.
-   */
-  public boolean autoZoomEnabled;
-
-  /** if multi-touch should be enabled on the crop box default: false */
-  public boolean multiTouchEnabled;
-
-  /** The max zoom allowed during cropping. */
-  public int maxZoom;
-
-  /**
-   * The initial crop window padding from image borders in percentage of the cropping image
-   * dimensions.
-   */
-  public float initialCropWindowPaddingRatio;
-
-  /** whether the width to height aspect ratio should be maintained or free to change. */
-  public boolean fixAspectRatio;
-
-  /** the X value of the aspect ratio. */
-  public int aspectRatioX;
-
-  /** the Y value of the aspect ratio. */
-  public int aspectRatioY;
-
-  /** the thickness of the guidelines lines in pixels. (in pixels) */
-  public float borderLineThickness;
-
-  /** the color of the guidelines lines */
-  public int borderLineColor;
-
-  /** thickness of the corner line. (in pixels) */
-  public float borderCornerThickness;
-
-  /** the offset of corner line from crop window border. (in pixels) */
-  public float borderCornerOffset;
-
-  /** the length of the corner line away from the corner. (in pixels) */
-  public float borderCornerLength;
-
-  /** the color of the corner line */
-  public int borderCornerColor;
-
-  /** the thickness of the guidelines lines. (in pixels) */
-  public float guidelinesThickness;
-
-  /** the color of the guidelines lines */
-  public int guidelinesColor;
-
-  /**
-   * the color of the overlay background around the crop window cover the image parts not in the
-   * crop window.
-   */
-  public int backgroundColor;
-
-  /** the min width the crop window is allowed to be. (in pixels) */
-  public int minCropWindowWidth;
-
-  /** the min height the crop window is allowed to be. (in pixels) */
-  public int minCropWindowHeight;
-
-  /**
-   * the min width the resulting cropping image is allowed to be, affects the cropping window
-   * limits. (in pixels)
-   */
-  public int minCropResultWidth;
-
-  /**
-   * the min height the resulting cropping image is allowed to be, affects the cropping window
-   * limits. (in pixels)
-   */
-  public int minCropResultHeight;
-
-  /**
-   * the max width the resulting cropping image is allowed to be, affects the cropping window
-   * limits. (in pixels)
-   */
-  public int maxCropResultWidth;
-
-  /**
-   * the max height the resulting cropping image is allowed to be, affects the cropping window
-   * limits. (in pixels)
-   */
-  public int maxCropResultHeight;
-
-  /** the title of the {@link CropImageActivity} */
-  public CharSequence activityTitle;
-
-  /** the color to use for action bar items icons */
-  public int activityMenuIconColor;
-
-  /** the Android Uri to save the cropped image to */
-  public Uri outputUri;
-
-  /** the compression format to use when writing the image */
-  public Bitmap.CompressFormat outputCompressFormat;
-
-  /** the quality (if applicable) to use when writing the image (0 - 100) */
-  public int outputCompressQuality;
-
-  /** the width to resize the cropped image to (see options) */
-  public int outputRequestWidth;
-
-  /** the height to resize the cropped image to (see options) */
-  public int outputRequestHeight;
-
-  /** the resize method to use on the cropped bitmap (see options documentation) */
-  public CropImageView.RequestSizeOptions outputRequestSizeOptions;
-
-  /** if the result of crop image activity should not save the cropped image bitmap */
-  public boolean noOutputImage;
-
-  /** the initial rectangle to set on the cropping image after loading */
-  public Rect initialCropWindowRectangle;
-
-  /** the initial rotation to set on the cropping image after loading (0-360 degrees clockwise) */
-  public int initialRotation;
-
-  /** if to allow (all) rotation during cropping (activity) */
-  public boolean allowRotation;
-
-  /** if to allow (all) flipping during cropping (activity) */
-  public boolean allowFlipping;
-
-  /** if to allow counter-clockwise rotation during cropping (activity) */
-  public boolean allowCounterRotation;
-
-  /** the amount of degrees to rotate clockwise or counter-clockwise */
-  public int rotationDegrees;
-
-  /** whether the image should be flipped horizontally */
-  public boolean flipHorizontally;
-
-  /** whether the image should be flipped vertically */
-  public boolean flipVertically;
-
-  /** optional, the text of the crop menu crop button */
-  public CharSequence cropMenuCropButtonTitle;
-
-  /** optional image resource to be used for crop menu crop icon instead of text */
-  public int cropMenuCropButtonIcon;
-
-  /** Init options with defaults. */
-  public CropImageOptions() {
-
-    DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
-
-    cropShape = CropImageView.CropShape.RECTANGLE;
-    snapRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, dm);
-    touchRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, dm);
-    guidelines = CropImageView.Guidelines.ON_TOUCH;
-    scaleType = CropImageView.ScaleType.FIT_CENTER;
-    showCropOverlay = true;
-    showProgressBar = true;
-    autoZoomEnabled = true;
-    multiTouchEnabled = false;
-    maxZoom = 4;
-    initialCropWindowPaddingRatio = 0.1f;
-
-    fixAspectRatio = false;
-    aspectRatioX = 1;
-    aspectRatioY = 1;
-
-    //borderLineThickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, dm);
-    // 自定义裁剪-没有边界
-    borderLineThickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, dm);
-    borderLineColor = Color.argb(170, 255, 255, 255);
-    borderCornerThickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, dm);
-    //borderCornerOffset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, dm);
-    // 自定义裁剪-没有边距
-    borderCornerOffset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, dm);
-    borderCornerLength = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, dm);
-    // 自定义裁剪-边角颜色
-    borderCornerColor = Color.parseColor("#12ABE3");
-    //borderCornerColor = Color.WHITE;
-
-    // 自定义裁剪-网格线
-    guidelinesThickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, dm);
-    //guidelinesThickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, dm);
-    guidelinesColor = Color.argb(170, 255, 255, 255);
-    backgroundColor = Color.argb(119, 0, 0, 0);
-
-    minCropWindowWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 42, dm);
-    minCropWindowHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 42, dm);
-    minCropResultWidth = 40;
-    minCropResultHeight = 40;
-    maxCropResultWidth = 99999;
-    maxCropResultHeight = 99999;
-
-    activityTitle = "";
-    activityMenuIconColor = 0;
-
-    outputUri = Uri.EMPTY;
-    outputCompressFormat = Bitmap.CompressFormat.JPEG;
-    outputCompressQuality = 90;
-    outputRequestWidth = 0;
-    outputRequestHeight = 0;
-    outputRequestSizeOptions = CropImageView.RequestSizeOptions.NONE;
-    noOutputImage = false;
-
-    initialCropWindowRectangle = null;
-    initialRotation = -1;
-    allowRotation = true;
-    allowFlipping = true;
-    allowCounterRotation = false;
-    rotationDegrees = 90;
-    flipHorizontally = false;
-    flipVertically = false;
-    cropMenuCropButtonTitle = null;
-
-    cropMenuCropButtonIcon = 0;
-  }
-
-  /** Create object from parcel. */
-  protected CropImageOptions(Parcel in) {
-    cropShape = CropImageView.CropShape.values()[in.readInt()];
-    snapRadius = in.readFloat();
-    touchRadius = in.readFloat();
-    guidelines = CropImageView.Guidelines.values()[in.readInt()];
-    scaleType = CropImageView.ScaleType.values()[in.readInt()];
-    showCropOverlay = in.readByte() != 0;
-    showProgressBar = in.readByte() != 0;
-    autoZoomEnabled = in.readByte() != 0;
-    multiTouchEnabled = in.readByte() != 0;
-    maxZoom = in.readInt();
-    initialCropWindowPaddingRatio = in.readFloat();
-    fixAspectRatio = in.readByte() != 0;
-    aspectRatioX = in.readInt();
-    aspectRatioY = in.readInt();
-    borderLineThickness = in.readFloat();
-    borderLineColor = in.readInt();
-    borderCornerThickness = in.readFloat();
-    borderCornerOffset = in.readFloat();
-    borderCornerLength = in.readFloat();
-    borderCornerColor = in.readInt();
-    guidelinesThickness = in.readFloat();
-    guidelinesColor = in.readInt();
-    backgroundColor = in.readInt();
-    minCropWindowWidth = in.readInt();
-    minCropWindowHeight = in.readInt();
-    minCropResultWidth = in.readInt();
-    minCropResultHeight = in.readInt();
-    maxCropResultWidth = in.readInt();
-    maxCropResultHeight = in.readInt();
-    activityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
-    activityMenuIconColor = in.readInt();
-    outputUri = in.readParcelable(Uri.class.getClassLoader());
-    outputCompressFormat = Bitmap.CompressFormat.valueOf(in.readString());
-    outputCompressQuality = in.readInt();
-    outputRequestWidth = in.readInt();
-    outputRequestHeight = in.readInt();
-    outputRequestSizeOptions = CropImageView.RequestSizeOptions.values()[in.readInt()];
-    noOutputImage = in.readByte() != 0;
-    initialCropWindowRectangle = in.readParcelable(Rect.class.getClassLoader());
-    initialRotation = in.readInt();
-    allowRotation = in.readByte() != 0;
-    allowFlipping = in.readByte() != 0;
-    allowCounterRotation = in.readByte() != 0;
-    rotationDegrees = in.readInt();
-    flipHorizontally = in.readByte() != 0;
-    flipVertically = in.readByte() != 0;
-    cropMenuCropButtonTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
-    cropMenuCropButtonIcon = in.readInt();
-  }
-
-  @Override
-  public void writeToParcel(Parcel dest, int flags) {
-    dest.writeInt(cropShape.ordinal());
-    dest.writeFloat(snapRadius);
-    dest.writeFloat(touchRadius);
-    dest.writeInt(guidelines.ordinal());
-    dest.writeInt(scaleType.ordinal());
-    dest.writeByte((byte) (showCropOverlay ? 1 : 0));
-    dest.writeByte((byte) (showProgressBar ? 1 : 0));
-    dest.writeByte((byte) (autoZoomEnabled ? 1 : 0));
-    dest.writeByte((byte) (multiTouchEnabled ? 1 : 0));
-    dest.writeInt(maxZoom);
-    dest.writeFloat(initialCropWindowPaddingRatio);
-    dest.writeByte((byte) (fixAspectRatio ? 1 : 0));
-    dest.writeInt(aspectRatioX);
-    dest.writeInt(aspectRatioY);
-    dest.writeFloat(borderLineThickness);
-    dest.writeInt(borderLineColor);
-    dest.writeFloat(borderCornerThickness);
-    dest.writeFloat(borderCornerOffset);
-    dest.writeFloat(borderCornerLength);
-    dest.writeInt(borderCornerColor);
-    dest.writeFloat(guidelinesThickness);
-    dest.writeInt(guidelinesColor);
-    dest.writeInt(backgroundColor);
-    dest.writeInt(minCropWindowWidth);
-    dest.writeInt(minCropWindowHeight);
-    dest.writeInt(minCropResultWidth);
-    dest.writeInt(minCropResultHeight);
-    dest.writeInt(maxCropResultWidth);
-    dest.writeInt(maxCropResultHeight);
-    TextUtils.writeToParcel(activityTitle, dest, flags);
-    dest.writeInt(activityMenuIconColor);
-    dest.writeParcelable(outputUri, flags);
-    dest.writeString(outputCompressFormat.name());
-    dest.writeInt(outputCompressQuality);
-    dest.writeInt(outputRequestWidth);
-    dest.writeInt(outputRequestHeight);
-    dest.writeInt(outputRequestSizeOptions.ordinal());
-    dest.writeInt(noOutputImage ? 1 : 0);
-    dest.writeParcelable(initialCropWindowRectangle, flags);
-    dest.writeInt(initialRotation);
-    dest.writeByte((byte) (allowRotation ? 1 : 0));
-    dest.writeByte((byte) (allowFlipping ? 1 : 0));
-    dest.writeByte((byte) (allowCounterRotation ? 1 : 0));
-    dest.writeInt(rotationDegrees);
-    dest.writeByte((byte) (flipHorizontally ? 1 : 0));
-    dest.writeByte((byte) (flipVertically ? 1 : 0));
-    TextUtils.writeToParcel(cropMenuCropButtonTitle, dest, flags);
-    dest.writeInt(cropMenuCropButtonIcon);
-  }
-
-  @Override
-  public int describeContents() {
-    return 0;
-  }
-
-  /**
-   * Validate all the options are withing valid range.
-   *
-   * @throws IllegalArgumentException if any of the options is not valid
-   */
-  public void validate() {
-    if (maxZoom < 0) {
-      throw new IllegalArgumentException("Cannot set max zoom to a number < 1");
-    }
-    if (touchRadius < 0) {
-      throw new IllegalArgumentException("Cannot set touch radius value to a number <= 0 ");
-    }
-    if (initialCropWindowPaddingRatio < 0 || initialCropWindowPaddingRatio >= 0.5) {
-      throw new IllegalArgumentException(
-          "Cannot set initial crop window padding value to a number < 0 or >= 0.5");
-    }
-    if (aspectRatioX <= 0) {
-      throw new IllegalArgumentException(
-          "Cannot set aspect ratio value to a number less than or equal to 0.");
-    }
-    if (aspectRatioY <= 0) {
-      throw new IllegalArgumentException(
-          "Cannot set aspect ratio value to a number less than or equal to 0.");
-    }
-    if (borderLineThickness < 0) {
-      throw new IllegalArgumentException(
-          "Cannot set line thickness value to a number less than 0.");
-    }
-    if (borderCornerThickness < 0) {
-      throw new IllegalArgumentException(
-          "Cannot set corner thickness value to a number less than 0.");
-    }
-    if (guidelinesThickness < 0) {
-      throw new IllegalArgumentException(
-          "Cannot set guidelines thickness value to a number less than 0.");
-    }
-    if (minCropWindowHeight < 0) {
-      throw new IllegalArgumentException(
-          "Cannot set min crop window height value to a number < 0 ");
-    }
-    if (minCropResultWidth < 0) {
-      throw new IllegalArgumentException("Cannot set min crop result width value to a number < 0 ");
-    }
-    if (minCropResultHeight < 0) {
-      throw new IllegalArgumentException(
-          "Cannot set min crop result height value to a number < 0 ");
-    }
-    if (maxCropResultWidth < minCropResultWidth) {
-      throw new IllegalArgumentException(
-          "Cannot set max crop result width to smaller value than min crop result width");
-    }
-    if (maxCropResultHeight < minCropResultHeight) {
-      throw new IllegalArgumentException(
-          "Cannot set max crop result height to smaller value than min crop result height");
-    }
-    if (outputRequestWidth < 0) {
-      throw new IllegalArgumentException("Cannot set request width value to a number < 0 ");
-    }
-    if (outputRequestHeight < 0) {
-      throw new IllegalArgumentException("Cannot set request height value to a number < 0 ");
-    }
-    if (rotationDegrees < 0 || rotationDegrees > 360) {
-      throw new IllegalArgumentException(
-          "Cannot set rotation degrees value to a number < 0 or > 360");
-    }
-  }
-}

Plik diff jest za duży
+ 0 - 2140
app/src/main/java/com/miekir/ocr/view/cropper/CropImageView.java


Plik diff jest za duży
+ 0 - 1043
app/src/main/java/com/miekir/ocr/view/cropper/CropOverlayView.java


+ 0 - 373
app/src/main/java/com/miekir/ocr/view/cropper/CropWindowHandler.java

@@ -1,373 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth,
-// inexhaustible as the great rivers.
-// When they come to an end,
-// they begin again,
-// like the days and months;
-// they die and are reborn,
-// like the four seasons."
-//
-// - Sun Tsu,
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.graphics.RectF;
-
-/** Handler from crop window stuff, moving and knowing possition. */
-final class CropWindowHandler {
-
-  // region: Fields and Consts
-
-  /** The 4 edges of the crop window defining its coordinates and size */
-  private final RectF mEdges = new RectF();
-
-  /**
-   * Rectangle used to return the edges rectangle without ability to change it and without creating
-   * new all the time.
-   */
-  private final RectF mGetEdges = new RectF();
-
-  /** Minimum width in pixels that the crop window can get. */
-  private float mMinCropWindowWidth;
-
-  /** Minimum height in pixels that the crop window can get. */
-  private float mMinCropWindowHeight;
-
-  /** Maximum width in pixels that the crop window can CURRENTLY get. */
-  private float mMaxCropWindowWidth;
-
-  /** Maximum height in pixels that the crop window can CURRENTLY get. */
-  private float mMaxCropWindowHeight;
-
-  /**
-   * Minimum width in pixels that the result of cropping an image can get, affects crop window width
-   * adjusted by width scale factor.
-   */
-  private float mMinCropResultWidth;
-
-  /**
-   * Minimum height in pixels that the result of cropping an image can get, affects crop window
-   * height adjusted by height scale factor.
-   */
-  private float mMinCropResultHeight;
-
-  /**
-   * Maximum width in pixels that the result of cropping an image can get, affects crop window width
-   * adjusted by width scale factor.
-   */
-  private float mMaxCropResultWidth;
-
-  /**
-   * Maximum height in pixels that the result of cropping an image can get, affects crop window
-   * height adjusted by height scale factor.
-   */
-  private float mMaxCropResultHeight;
-
-  /** The width scale factor of shown image and actual image */
-  private float mScaleFactorWidth = 1;
-
-  /** The height scale factor of shown image and actual image */
-  private float mScaleFactorHeight = 1;
-  // endregion
-
-  /** Get the left/top/right/bottom coordinates of the crop window. */
-  public RectF getRect() {
-    mGetEdges.set(mEdges);
-    return mGetEdges;
-  }
-
-  /** Minimum width in pixels that the crop window can get. */
-  public float getMinCropWidth() {
-    return Math.max(mMinCropWindowWidth, mMinCropResultWidth / mScaleFactorWidth);
-  }
-
-  /** Minimum height in pixels that the crop window can get. */
-  public float getMinCropHeight() {
-    return Math.max(mMinCropWindowHeight, mMinCropResultHeight / mScaleFactorHeight);
-  }
-
-  /** Maximum width in pixels that the crop window can get. */
-  public float getMaxCropWidth() {
-    return Math.min(mMaxCropWindowWidth, mMaxCropResultWidth / mScaleFactorWidth);
-  }
-
-  /** Maximum height in pixels that the crop window can get. */
-  public float getMaxCropHeight() {
-    // 自定义裁剪-高度
-    //return SizeTool.SCREEN_HEIGHT;
-    return Math.min(mMaxCropWindowHeight, mMaxCropResultHeight / mScaleFactorHeight);
-  }
-
-  /** get the scale factor (on width) of the showen image to original image. */
-  public float getScaleFactorWidth() {
-    return mScaleFactorWidth;
-  }
-
-  /** get the scale factor (on height) of the showen image to original image. */
-  public float getScaleFactorHeight() {
-    return mScaleFactorHeight;
-  }
-
-  /**
-   * the min size the resulting cropping image is allowed to be, affects the cropping window limits
-   * (in pixels).<br>
-   */
-  public void setMinCropResultSize(int minCropResultWidth, int minCropResultHeight) {
-    mMinCropResultWidth = minCropResultWidth;
-    mMinCropResultHeight = minCropResultHeight;
-  }
-
-  /**
-   * the max size the resulting cropping image is allowed to be, affects the cropping window limits
-   * (in pixels).<br>
-   */
-  public void setMaxCropResultSize(int maxCropResultWidth, int maxCropResultHeight) {
-    mMaxCropResultWidth = maxCropResultWidth;
-    mMaxCropResultHeight = maxCropResultHeight;
-  }
-
-  /**
-   * set the max width/height and scale factor of the showen image to original image to scale the
-   * limits appropriately.
-   */
-  public void setCropWindowLimits(
-      float maxWidth, float maxHeight, float scaleFactorWidth, float scaleFactorHeight) {
-    mMaxCropWindowWidth = maxWidth;
-    mMaxCropWindowHeight = maxHeight;
-    mScaleFactorWidth = scaleFactorWidth;
-    mScaleFactorHeight = scaleFactorHeight;
-  }
-
-  /** Set the variables to be used during crop window handling. */
-  public void setInitialAttributeValues(CropImageOptions options) {
-    mMinCropWindowWidth = options.minCropWindowWidth;
-    mMinCropWindowHeight = options.minCropWindowHeight;
-    mMinCropResultWidth = options.minCropResultWidth;
-    mMinCropResultHeight = options.minCropResultHeight;
-    mMaxCropResultWidth = options.maxCropResultWidth;
-    mMaxCropResultHeight = options.maxCropResultHeight;
-  }
-
-  /** Set the left/top/right/bottom coordinates of the crop window. */
-  public void setRect(RectF rect) {
-    mEdges.set(rect);
-  }
-
-  /**
-   * Indicates whether the crop window is small enough that the guidelines should be shown. Public
-   * because this function is also used to determine if the center handle should be focused.
-   *
-   * @return boolean Whether the guidelines should be shown or not
-   */
-  public boolean showGuidelines() {
-    return !(mEdges.width() < 100 || mEdges.height() < 100);
-  }
-
-  /**
-   * Determines which, if any, of the handles are pressed given the touch coordinates, the bounding
-   * box, and the touch radius.
-   *
-   * @param x the x-coordinate of the touch point
-   * @param y the y-coordinate of the touch point
-   * @param targetRadius the target radius in pixels
-   * @return the Handle that was pressed; null if no Handle was pressed
-   */
-  public CropWindowMoveHandler getMoveHandler(
-      float x, float y, float targetRadius, CropImageView.CropShape cropShape) {
-    CropWindowMoveHandler.Type type =
-        cropShape == CropImageView.CropShape.OVAL
-            ? getOvalPressedMoveType(x, y)
-            : getRectanglePressedMoveType(x, y, targetRadius);
-    return type != null ? new CropWindowMoveHandler(type, this, x, y) : null;
-  }
-
-  // region: Private methods
-
-  /**
-   * Determines which, if any, of the handles are pressed given the touch coordinates, the bounding
-   * box, and the touch radius.
-   *
-   * @param x the x-coordinate of the touch point
-   * @param y the y-coordinate of the touch point
-   * @param targetRadius the target radius in pixels
-   * @return the Handle that was pressed; null if no Handle was pressed
-   */
-  private CropWindowMoveHandler.Type getRectanglePressedMoveType(
-      float x, float y, float targetRadius) {
-    CropWindowMoveHandler.Type moveType = null;
-
-    // Note: corner-handles take precedence, then side-handles, then center.
-    if (CropWindowHandler.isInCornerTargetZone(x, y, mEdges.left, mEdges.top, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.TOP_LEFT;
-    } else if (CropWindowHandler.isInCornerTargetZone(
-        x, y, mEdges.right, mEdges.top, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.TOP_RIGHT;
-    } else if (CropWindowHandler.isInCornerTargetZone(
-        x, y, mEdges.left, mEdges.bottom, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.BOTTOM_LEFT;
-    } else if (CropWindowHandler.isInCornerTargetZone(
-        x, y, mEdges.right, mEdges.bottom, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.BOTTOM_RIGHT;
-    } else if (CropWindowHandler.isInCenterTargetZone(
-            x, y, mEdges.left, mEdges.top, mEdges.right, mEdges.bottom)
-        && focusCenter()) {
-      moveType = CropWindowMoveHandler.Type.CENTER;
-    } else if (CropWindowHandler.isInHorizontalTargetZone(
-        x, y, mEdges.left, mEdges.right, mEdges.top, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.TOP;
-    } else if (CropWindowHandler.isInHorizontalTargetZone(
-        x, y, mEdges.left, mEdges.right, mEdges.bottom, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.BOTTOM;
-    } else if (CropWindowHandler.isInVerticalTargetZone(
-        x, y, mEdges.left, mEdges.top, mEdges.bottom, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.LEFT;
-    } else if (CropWindowHandler.isInVerticalTargetZone(
-        x, y, mEdges.right, mEdges.top, mEdges.bottom, targetRadius)) {
-      moveType = CropWindowMoveHandler.Type.RIGHT;
-    } else if (CropWindowHandler.isInCenterTargetZone(
-            x, y, mEdges.left, mEdges.top, mEdges.right, mEdges.bottom)
-        && !focusCenter()) {
-      moveType = CropWindowMoveHandler.Type.CENTER;
-    }
-
-    return moveType;
-  }
-
-  /**
-   * Determines which, if any, of the handles are pressed given the touch coordinates, the bounding
-   * box/oval, and the touch radius.
-   *
-   * @param x the x-coordinate of the touch point
-   * @param y the y-coordinate of the touch point
-   * @return the Handle that was pressed; null if no Handle was pressed
-   */
-  private CropWindowMoveHandler.Type getOvalPressedMoveType(float x, float y) {
-
-    /*
-       Use a 6x6 grid system divided into 9 "handles", with the center the biggest region. While
-       this is not perfect, it's a good quick-to-ship approach.
-
-       TL T T T T TR
-        L C C C C R
-        L C C C C R
-        L C C C C R
-        L C C C C R
-       BL B B B B BR
-    */
-
-    float cellLength = mEdges.width() / 6;
-    float leftCenter = mEdges.left + cellLength;
-    float rightCenter = mEdges.left + (5 * cellLength);
-
-    float cellHeight = mEdges.height() / 6;
-    float topCenter = mEdges.top + cellHeight;
-    float bottomCenter = mEdges.top + 5 * cellHeight;
-
-    CropWindowMoveHandler.Type moveType;
-    if (x < leftCenter) {
-      if (y < topCenter) {
-        moveType = CropWindowMoveHandler.Type.TOP_LEFT;
-      } else if (y < bottomCenter) {
-        moveType = CropWindowMoveHandler.Type.LEFT;
-      } else {
-        moveType = CropWindowMoveHandler.Type.BOTTOM_LEFT;
-      }
-    } else if (x < rightCenter) {
-      if (y < topCenter) {
-        moveType = CropWindowMoveHandler.Type.TOP;
-      } else if (y < bottomCenter) {
-        moveType = CropWindowMoveHandler.Type.CENTER;
-      } else {
-        moveType = CropWindowMoveHandler.Type.BOTTOM;
-      }
-    } else {
-      if (y < topCenter) {
-        moveType = CropWindowMoveHandler.Type.TOP_RIGHT;
-      } else if (y < bottomCenter) {
-        moveType = CropWindowMoveHandler.Type.RIGHT;
-      } else {
-        moveType = CropWindowMoveHandler.Type.BOTTOM_RIGHT;
-      }
-    }
-
-    return moveType;
-  }
-
-  /**
-   * Determines if the specified coordinate is in the target touch zone for a corner handle.
-   *
-   * @param x the x-coordinate of the touch point
-   * @param y the y-coordinate of the touch point
-   * @param handleX the x-coordinate of the corner handle
-   * @param handleY the y-coordinate of the corner handle
-   * @param targetRadius the target radius in pixels
-   * @return true if the touch point is in the target touch zone; false otherwise
-   */
-  private static boolean isInCornerTargetZone(
-      float x, float y, float handleX, float handleY, float targetRadius) {
-    return Math.abs(x - handleX) <= targetRadius && Math.abs(y - handleY) <= targetRadius;
-  }
-
-  /**
-   * Determines if the specified coordinate is in the target touch zone for a horizontal bar handle.
-   *
-   * @param x the x-coordinate of the touch point
-   * @param y the y-coordinate of the touch point
-   * @param handleXStart the left x-coordinate of the horizontal bar handle
-   * @param handleXEnd the right x-coordinate of the horizontal bar handle
-   * @param handleY the y-coordinate of the horizontal bar handle
-   * @param targetRadius the target radius in pixels
-   * @return true if the touch point is in the target touch zone; false otherwise
-   */
-  private static boolean isInHorizontalTargetZone(
-      float x, float y, float handleXStart, float handleXEnd, float handleY, float targetRadius) {
-    return x > handleXStart && x < handleXEnd && Math.abs(y - handleY) <= targetRadius;
-  }
-
-  /**
-   * Determines if the specified coordinate is in the target touch zone for a vertical bar handle.
-   *
-   * @param x the x-coordinate of the touch point
-   * @param y the y-coordinate of the touch point
-   * @param handleX the x-coordinate of the vertical bar handle
-   * @param handleYStart the top y-coordinate of the vertical bar handle
-   * @param handleYEnd the bottom y-coordinate of the vertical bar handle
-   * @param targetRadius the target radius in pixels
-   * @return true if the touch point is in the target touch zone; false otherwise
-   */
-  private static boolean isInVerticalTargetZone(
-      float x, float y, float handleX, float handleYStart, float handleYEnd, float targetRadius) {
-    return Math.abs(x - handleX) <= targetRadius && y > handleYStart && y < handleYEnd;
-  }
-
-  /**
-   * Determines if the specified coordinate falls anywhere inside the given bounds.
-   *
-   * @param x the x-coordinate of the touch point
-   * @param y the y-coordinate of the touch point
-   * @param left the x-coordinate of the left bound
-   * @param top the y-coordinate of the top bound
-   * @param right the x-coordinate of the right bound
-   * @param bottom the y-coordinate of the bottom bound
-   * @return true if the touch point is inside the bounding rectangle; false otherwise
-   */
-  private static boolean isInCenterTargetZone(
-      float x, float y, float left, float top, float right, float bottom) {
-    return x > left && x < right && y > top && y < bottom;
-  }
-
-  /**
-   * Determines if the cropper should focus on the center handle or the side handles. If it is a
-   * small image, focus on the center handle so the user can move it. If it is a large image, focus
-   * on the side handles so user can grab them. Corresponds to the appearance of the
-   * RuleOfThirdsGuidelines.
-   *
-   * @return true if it is small enough such that it should focus on the center; less than
-   *     show_guidelines limit
-   */
-  private boolean focusCenter() {
-    return !showGuidelines();
-  }
-  // endregion
-}

+ 0 - 766
app/src/main/java/com/miekir/ocr/view/cropper/CropWindowMoveHandler.java

@@ -1,766 +0,0 @@
-// "Therefore those skilled at the unorthodox
-// are infinite as heaven and earth,
-// inexhaustible as the great rivers.
-// When they come to an end,
-// they begin again,
-// like the days and months;
-// they die and are reborn,
-// like the four seasons."
-//
-// - Sun Tsu,
-// "The Art of War"
-
-package com.miekir.ocr.view.cropper;
-
-import android.graphics.Matrix;
-import android.graphics.PointF;
-import android.graphics.RectF;
-
-/**
- * Handler to update crop window edges by the move type - Horizontal, Vertical, Corner or Center.
- * <br>
- */
-final class CropWindowMoveHandler {
-
-  // region: Fields and Consts
-
-  /** Matrix used for rectangle rotation handling */
-  private static final Matrix MATRIX = new Matrix();
-
-  /** Minimum width in pixels that the crop window can get. */
-  private final float mMinCropWidth;
-
-  /** Minimum width in pixels that the crop window can get. */
-  private final float mMinCropHeight;
-
-  /** Maximum height in pixels that the crop window can get. */
-  private final float mMaxCropWidth;
-
-  /** Maximum height in pixels that the crop window can get. */
-  private final float mMaxCropHeight;
-
-  /** The type of crop window move that is handled. */
-  private final Type mType;
-
-  /**
-   * Holds the x and y offset between the exact touch location and the exact handle location that is
-   * activated. There may be an offset because we allow for some leeway (specified by mHandleRadius)
-   * in activating a handle. However, we want to maintain these offset values while the handle is
-   * being dragged so that the handle doesn't jump.
-   */
-  private final PointF mTouchOffset = new PointF();
-  // endregion
-
-  /**
-   * @param edgeMoveType the type of move this handler is executing
-   * @param horizontalEdge the primary edge associated with this handle; may be null
-   * @param verticalEdge the secondary edge associated with this handle; may be null
-   * @param cropWindowHandler main crop window handle to get and update the crop window edges
-   * @param touchX the location of the initial toch possition to measure move distance
-   * @param touchY the location of the initial toch possition to measure move distance
-   */
-  public CropWindowMoveHandler(
-      Type type, CropWindowHandler cropWindowHandler, float touchX, float touchY) {
-    mType = type;
-    mMinCropWidth = cropWindowHandler.getMinCropWidth();
-    mMinCropHeight = cropWindowHandler.getMinCropHeight();
-    mMaxCropWidth = cropWindowHandler.getMaxCropWidth();
-    mMaxCropHeight = cropWindowHandler.getMaxCropHeight();
-    calculateTouchOffset(cropWindowHandler.getRect(), touchX, touchY);
-  }
-
-  /**
-   * Updates the crop window by change in the toch location.<br>
-   * Move type handled by this instance, as initialized in creation, affects how the change in toch
-   * location changes the crop window position and size.<br>
-   * After the crop window position/size is changed by toch move it may result in values that
-   * vialate contraints: outside the bounds of the shown bitmap, smaller/larger than min/max size or
-   * missmatch in aspect ratio. So a series of fixes is executed on "secondary" edges to adjust it
-   * by the "primary" edge movement.<br>
-   * Primary is the edge directly affected by move type, secondary is the other edge.<br>
-   * The crop window is changed by directly setting the Edge coordinates.
-   *
-   * @param x the new x-coordinate of this handle
-   * @param y the new y-coordinate of this handle
-   * @param bounds the bounding rectangle of the image
-   * @param viewWidth The bounding image view width used to know the crop overlay is at view edges.
-   * @param viewHeight The bounding image view height used to know the crop overlay is at view
-   *     edges.
-   * @param parentView the parent View containing the image
-   * @param snapMargin the maximum distance (in pixels) at which the crop window should snap to the
-   *     image
-   * @param fixedAspectRatio is the aspect ration fixed and 'targetAspectRatio' should be used
-   * @param aspectRatio the aspect ratio to maintain
-   */
-  public void move(
-      RectF rect,
-      float x,
-      float y,
-      RectF bounds,
-      int viewWidth,
-      int viewHeight,
-      float snapMargin,
-      boolean fixedAspectRatio,
-      float aspectRatio) {
-
-    // Adjust the coordinates for the finger position's offset (i.e. the
-    // distance from the initial touch to the precise handle location).
-    // We want to maintain the initial touch's distance to the pressed
-    // handle so that the crop window size does not "jump".
-    float adjX = x + mTouchOffset.x;
-    float adjY = y + mTouchOffset.y;
-
-    if (mType == Type.CENTER) {
-      moveCenter(rect, adjX, adjY, bounds, viewWidth, viewHeight, snapMargin);
-    } else {
-      if (fixedAspectRatio) {
-        moveSizeWithFixedAspectRatio(
-            rect, adjX, adjY, bounds, viewWidth, viewHeight, snapMargin, aspectRatio);
-      } else {
-        moveSizeWithFreeAspectRatio(rect, adjX, adjY, bounds, viewWidth, viewHeight, snapMargin);
-      }
-    }
-  }
-
-  // region: Private methods
-
-  /**
-   * Calculates the offset of the touch point from the precise location of the specified handle.<br>
-   * Save these values in a member variable since we want to maintain this offset as we drag the
-   * handle.
-   */
-  private void calculateTouchOffset(RectF rect, float touchX, float touchY) {
-
-    float touchOffsetX = 0;
-    float touchOffsetY = 0;
-
-    // Calculate the offset from the appropriate handle.
-    switch (mType) {
-      case TOP_LEFT:
-        touchOffsetX = rect.left - touchX;
-        touchOffsetY = rect.top - touchY;
-        break;
-      case TOP_RIGHT:
-        touchOffsetX = rect.right - touchX;
-        touchOffsetY = rect.top - touchY;
-        break;
-      case BOTTOM_LEFT:
-        touchOffsetX = rect.left - touchX;
-        touchOffsetY = rect.bottom - touchY;
-        break;
-      case BOTTOM_RIGHT:
-        touchOffsetX = rect.right - touchX;
-        touchOffsetY = rect.bottom - touchY;
-        break;
-      case LEFT:
-        touchOffsetX = rect.left - touchX;
-        touchOffsetY = 0;
-        break;
-      case TOP:
-        touchOffsetX = 0;
-        touchOffsetY = rect.top - touchY;
-        break;
-      case RIGHT:
-        touchOffsetX = rect.right - touchX;
-        touchOffsetY = 0;
-        break;
-      case BOTTOM:
-        touchOffsetX = 0;
-        touchOffsetY = rect.bottom - touchY;
-        break;
-      case CENTER:
-        touchOffsetX = rect.centerX() - touchX;
-        touchOffsetY = rect.centerY() - touchY;
-        break;
-      default:
-        break;
-    }
-
-    mTouchOffset.x = touchOffsetX;
-    mTouchOffset.y = touchOffsetY;
-  }
-
-  /** Center move only changes the position of the crop window without changing the size. */
-  private void moveCenter(
-      RectF rect, float x, float y, RectF bounds, int viewWidth, int viewHeight, float snapRadius) {
-    float dx = x - rect.centerX();
-    float dy = y - rect.centerY();
-    if (rect.left + dx < 0
-        || rect.right + dx > viewWidth
-        || rect.left + dx < bounds.left
-        || rect.right + dx > bounds.right) {
-      dx /= 1.05f;
-      mTouchOffset.x -= dx / 2;
-    }
-    if (rect.top + dy < 0
-        || rect.bottom + dy > viewHeight
-        || rect.top + dy < bounds.top
-        || rect.bottom + dy > bounds.bottom) {
-      dy /= 1.05f;
-      mTouchOffset.y -= dy / 2;
-    }
-    rect.offset(dx, dy);
-    snapEdgesToBounds(rect, bounds, snapRadius);
-  }
-
-  /**
-   * Change the size of the crop window on the required edge (or edges for corner size move) without
-   * affecting "secondary" edges.<br>
-   * Only the primary edge(s) are fixed to stay within limits.
-   */
-  private void moveSizeWithFreeAspectRatio(
-      RectF rect, float x, float y, RectF bounds, int viewWidth, int viewHeight, float snapMargin) {
-    switch (mType) {
-      case TOP_LEFT:
-        adjustTop(rect, y, bounds, snapMargin, 0, false, false);
-        adjustLeft(rect, x, bounds, snapMargin, 0, false, false);
-        break;
-      case TOP_RIGHT:
-        adjustTop(rect, y, bounds, snapMargin, 0, false, false);
-        adjustRight(rect, x, bounds, viewWidth, snapMargin, 0, false, false);
-        break;
-      case BOTTOM_LEFT:
-        adjustBottom(rect, y, bounds, viewHeight, snapMargin, 0, false, false);
-        adjustLeft(rect, x, bounds, snapMargin, 0, false, false);
-        break;
-      case BOTTOM_RIGHT:
-        adjustBottom(rect, y, bounds, viewHeight, snapMargin, 0, false, false);
-        adjustRight(rect, x, bounds, viewWidth, snapMargin, 0, false, false);
-        break;
-      case LEFT:
-        adjustLeft(rect, x, bounds, snapMargin, 0, false, false);
-        break;
-      case TOP:
-        adjustTop(rect, y, bounds, snapMargin, 0, false, false);
-        break;
-      case RIGHT:
-        adjustRight(rect, x, bounds, viewWidth, snapMargin, 0, false, false);
-        break;
-      case BOTTOM:
-        adjustBottom(rect, y, bounds, viewHeight, snapMargin, 0, false, false);
-        break;
-      default:
-        break;
-    }
-  }
-
-  /**
-   * Change the size of the crop window on the required "primary" edge WITH affect to relevant
-   * "secondary" edge via aspect ratio.<br>
-   * Example: change in the left edge (primary) will affect top and bottom edges (secondary) to
-   * preserve the given aspect ratio.
-   */
-  private void moveSizeWithFixedAspectRatio(
-      RectF rect,
-      float x,
-      float y,
-      RectF bounds,
-      int viewWidth,
-      int viewHeight,
-      float snapMargin,
-      float aspectRatio) {
-    switch (mType) {
-      case TOP_LEFT:
-        if (calculateAspectRatio(x, y, rect.right, rect.bottom) < aspectRatio) {
-          adjustTop(rect, y, bounds, snapMargin, aspectRatio, true, false);
-          adjustLeftByAspectRatio(rect, aspectRatio);
-        } else {
-          adjustLeft(rect, x, bounds, snapMargin, aspectRatio, true, false);
-          adjustTopByAspectRatio(rect, aspectRatio);
-        }
-        break;
-      case TOP_RIGHT:
-        if (calculateAspectRatio(rect.left, y, x, rect.bottom) < aspectRatio) {
-          adjustTop(rect, y, bounds, snapMargin, aspectRatio, false, true);
-          adjustRightByAspectRatio(rect, aspectRatio);
-        } else {
-          adjustRight(rect, x, bounds, viewWidth, snapMargin, aspectRatio, true, false);
-          adjustTopByAspectRatio(rect, aspectRatio);
-        }
-        break;
-      case BOTTOM_LEFT:
-        if (calculateAspectRatio(x, rect.top, rect.right, y) < aspectRatio) {
-          adjustBottom(rect, y, bounds, viewHeight, snapMargin, aspectRatio, true, false);
-          adjustLeftByAspectRatio(rect, aspectRatio);
-        } else {
-          adjustLeft(rect, x, bounds, snapMargin, aspectRatio, false, true);
-          adjustBottomByAspectRatio(rect, aspectRatio);
-        }
-        break;
-      case BOTTOM_RIGHT:
-        if (calculateAspectRatio(rect.left, rect.top, x, y) < aspectRatio) {
-          adjustBottom(rect, y, bounds, viewHeight, snapMargin, aspectRatio, false, true);
-          adjustRightByAspectRatio(rect, aspectRatio);
-        } else {
-          adjustRight(rect, x, bounds, viewWidth, snapMargin, aspectRatio, false, true);
-          adjustBottomByAspectRatio(rect, aspectRatio);
-        }
-        break;
-      case LEFT:
-        adjustLeft(rect, x, bounds, snapMargin, aspectRatio, true, true);
-        adjustTopBottomByAspectRatio(rect, bounds, aspectRatio);
-        break;
-      case TOP:
-        adjustTop(rect, y, bounds, snapMargin, aspectRatio, true, true);
-        adjustLeftRightByAspectRatio(rect, bounds, aspectRatio);
-        break;
-      case RIGHT:
-        adjustRight(rect, x, bounds, viewWidth, snapMargin, aspectRatio, true, true);
-        adjustTopBottomByAspectRatio(rect, bounds, aspectRatio);
-        break;
-      case BOTTOM:
-        adjustBottom(rect, y, bounds, viewHeight, snapMargin, aspectRatio, true, true);
-        adjustLeftRightByAspectRatio(rect, bounds, aspectRatio);
-        break;
-      default:
-        break;
-    }
-  }
-
-  /** Check if edges have gone out of bounds (including snap margin), and fix if needed. */
-  private void snapEdgesToBounds(RectF edges, RectF bounds, float margin) {
-    if (edges.left < bounds.left + margin) {
-      edges.offset(bounds.left - edges.left, 0);
-    }
-    if (edges.top < bounds.top + margin) {
-      edges.offset(0, bounds.top - edges.top);
-    }
-    if (edges.right > bounds.right - margin) {
-      edges.offset(bounds.right - edges.right, 0);
-    }
-    if (edges.bottom > bounds.bottom - margin) {
-      edges.offset(0, bounds.bottom - edges.bottom);
-    }
-  }
-
-  /**
-   * Get the resulting x-position of the left edge of the crop window given the handle's position
-   * and the image's bounding box and snap radius.
-   *
-   * @param left the position that the left edge is dragged to
-   * @param bounds the bounding box of the image that is being cropped
-   * @param snapMargin the snap distance to the image edge (in pixels)
-   */
-  private void adjustLeft(
-      RectF rect,
-      float left,
-      RectF bounds,
-      float snapMargin,
-      float aspectRatio,
-      boolean topMoves,
-      boolean bottomMoves) {
-
-    float newLeft = left;
-
-    if (newLeft < 0) {
-      newLeft /= 1.05f;
-      mTouchOffset.x -= newLeft / 1.1f;
-    }
-
-    if (newLeft < bounds.left) {
-      mTouchOffset.x -= (newLeft - bounds.left) / 2f;
-    }
-
-    if (newLeft - bounds.left < snapMargin) {
-      newLeft = bounds.left;
-    }
-
-    // Checks if the window is too small horizontally
-    if (rect.right - newLeft < mMinCropWidth) {
-      newLeft = rect.right - mMinCropWidth;
-    }
-
-    // Checks if the window is too large horizontally
-    if (rect.right - newLeft > mMaxCropWidth) {
-      newLeft = rect.right - mMaxCropWidth;
-    }
-
-    if (newLeft - bounds.left < snapMargin) {
-      newLeft = bounds.left;
-    }
-
-    // check vertical bounds if aspect ratio is in play
-    if (aspectRatio > 0) {
-      float newHeight = (rect.right - newLeft) / aspectRatio;
-
-      // Checks if the window is too small vertically
-      if (newHeight < mMinCropHeight) {
-        newLeft = Math.max(bounds.left, rect.right - mMinCropHeight * aspectRatio);
-        newHeight = (rect.right - newLeft) / aspectRatio;
-      }
-
-      // Checks if the window is too large vertically
-      if (newHeight > mMaxCropHeight) {
-        newLeft = Math.max(bounds.left, rect.right - mMaxCropHeight * aspectRatio);
-        newHeight = (rect.right - newLeft) / aspectRatio;
-      }
-
-      // if top AND bottom edge moves by aspect ratio check that it is within full height bounds
-      if (topMoves && bottomMoves) {
-        newLeft =
-            Math.max(newLeft, Math.max(bounds.left, rect.right - bounds.height() * aspectRatio));
-      } else {
-        // if top edge moves by aspect ratio check that it is within bounds
-        if (topMoves && rect.bottom - newHeight < bounds.top) {
-          newLeft = Math.max(bounds.left, rect.right - (rect.bottom - bounds.top) * aspectRatio);
-          newHeight = (rect.right - newLeft) / aspectRatio;
-        }
-
-        // if bottom edge moves by aspect ratio check that it is within bounds
-        if (bottomMoves && rect.top + newHeight > bounds.bottom) {
-          newLeft =
-              Math.max(
-                  newLeft,
-                  Math.max(bounds.left, rect.right - (bounds.bottom - rect.top) * aspectRatio));
-        }
-      }
-    }
-
-    rect.left = newLeft;
-  }
-
-  /**
-   * Get the resulting x-position of the right edge of the crop window given the handle's position
-   * and the image's bounding box and snap radius.
-   *
-   * @param right the position that the right edge is dragged to
-   * @param bounds the bounding box of the image that is being cropped
-   * @param viewWidth
-   * @param snapMargin the snap distance to the image edge (in pixels)
-   */
-  private void adjustRight(
-      RectF rect,
-      float right,
-      RectF bounds,
-      int viewWidth,
-      float snapMargin,
-      float aspectRatio,
-      boolean topMoves,
-      boolean bottomMoves) {
-
-    float newRight = right;
-
-    if (newRight > viewWidth) {
-      newRight = viewWidth + (newRight - viewWidth) / 1.05f;
-      mTouchOffset.x -= (newRight - viewWidth) / 1.1f;
-    }
-
-    if (newRight > bounds.right) {
-      mTouchOffset.x -= (newRight - bounds.right) / 2f;
-    }
-
-    // If close to the edge
-    if (bounds.right - newRight < snapMargin) {
-      newRight = bounds.right;
-    }
-
-    // Checks if the window is too small horizontally
-    if (newRight - rect.left < mMinCropWidth) {
-      newRight = rect.left + mMinCropWidth;
-    }
-
-    // Checks if the window is too large horizontally
-    if (newRight - rect.left > mMaxCropWidth) {
-      newRight = rect.left + mMaxCropWidth;
-    }
-
-    // If close to the edge
-    if (bounds.right - newRight < snapMargin) {
-      newRight = bounds.right;
-    }
-
-    // check vertical bounds if aspect ratio is in play
-    if (aspectRatio > 0) {
-      float newHeight = (newRight - rect.left) / aspectRatio;
-
-      // Checks if the window is too small vertically
-      if (newHeight < mMinCropHeight) {
-        newRight = Math.min(bounds.right, rect.left + mMinCropHeight * aspectRatio);
-        newHeight = (newRight - rect.left) / aspectRatio;
-      }
-
-      // Checks if the window is too large vertically
-      if (newHeight > mMaxCropHeight) {
-        newRight = Math.min(bounds.right, rect.left + mMaxCropHeight * aspectRatio);
-        newHeight = (newRight - rect.left) / aspectRatio;
-      }
-
-      // if top AND bottom edge moves by aspect ratio check that it is within full height bounds
-      if (topMoves && bottomMoves) {
-        newRight =
-            Math.min(newRight, Math.min(bounds.right, rect.left + bounds.height() * aspectRatio));
-      } else {
-        // if top edge moves by aspect ratio check that it is within bounds
-        if (topMoves && rect.bottom - newHeight < bounds.top) {
-          newRight = Math.min(bounds.right, rect.left + (rect.bottom - bounds.top) * aspectRatio);
-          newHeight = (newRight - rect.left) / aspectRatio;
-        }
-
-        // if bottom edge moves by aspect ratio check that it is within bounds
-        if (bottomMoves && rect.top + newHeight > bounds.bottom) {
-          newRight =
-              Math.min(
-                  newRight,
-                  Math.min(bounds.right, rect.left + (bounds.bottom - rect.top) * aspectRatio));
-        }
-      }
-    }
-
-    rect.right = newRight;
-  }
-
-  /**
-   * Get the resulting y-position of the top edge of the crop window given the handle's position and
-   * the image's bounding box and snap radius.
-   *
-   * @param top the x-position that the top edge is dragged to
-   * @param bounds the bounding box of the image that is being cropped
-   * @param snapMargin the snap distance to the image edge (in pixels)
-   */
-  private void adjustTop(
-      RectF rect,
-      float top,
-      RectF bounds,
-      float snapMargin,
-      float aspectRatio,
-      boolean leftMoves,
-      boolean rightMoves) {
-
-    float newTop = top;
-
-    if (newTop < 0) {
-      newTop /= 1.05f;
-      mTouchOffset.y -= newTop / 1.1f;
-    }
-
-    if (newTop < bounds.top) {
-      mTouchOffset.y -= (newTop - bounds.top) / 2f;
-    }
-
-    if (newTop - bounds.top < snapMargin) {
-      newTop = bounds.top;
-    }
-
-    // Checks if the window is too small vertically
-    if (rect.bottom - newTop < mMinCropHeight) {
-      newTop = rect.bottom - mMinCropHeight;
-    }
-
-    // Checks if the window is too large vertically
-    if (rect.bottom - newTop > mMaxCropHeight) {
-      newTop = rect.bottom - mMaxCropHeight;
-    }
-
-    if (newTop - bounds.top < snapMargin) {
-      newTop = bounds.top;
-    }
-
-    // check horizontal bounds if aspect ratio is in play
-    if (aspectRatio > 0) {
-      float newWidth = (rect.bottom - newTop) * aspectRatio;
-
-      // Checks if the crop window is too small horizontally due to aspect ratio adjustment
-      if (newWidth < mMinCropWidth) {
-        newTop = Math.max(bounds.top, rect.bottom - (mMinCropWidth / aspectRatio));
-        newWidth = (rect.bottom - newTop) * aspectRatio;
-      }
-
-      // Checks if the crop window is too large horizontally due to aspect ratio adjustment
-      if (newWidth > mMaxCropWidth) {
-        newTop = Math.max(bounds.top, rect.bottom - (mMaxCropWidth / aspectRatio));
-        newWidth = (rect.bottom - newTop) * aspectRatio;
-      }
-
-      // if left AND right edge moves by aspect ratio check that it is within full width bounds
-      if (leftMoves && rightMoves) {
-        newTop = Math.max(newTop, Math.max(bounds.top, rect.bottom - bounds.width() / aspectRatio));
-      } else {
-        // if left edge moves by aspect ratio check that it is within bounds
-        if (leftMoves && rect.right - newWidth < bounds.left) {
-          newTop = Math.max(bounds.top, rect.bottom - (rect.right - bounds.left) / aspectRatio);
-          newWidth = (rect.bottom - newTop) * aspectRatio;
-        }
-
-        // if right edge moves by aspect ratio check that it is within bounds
-        if (rightMoves && rect.left + newWidth > bounds.right) {
-          newTop =
-              Math.max(
-                  newTop,
-                  Math.max(bounds.top, rect.bottom - (bounds.right - rect.left) / aspectRatio));
-        }
-      }
-    }
-
-    rect.top = newTop;
-  }
-
-  /**
-   * Get the resulting y-position of the bottom edge of the crop window given the handle's position
-   * and the image's bounding box and snap radius.
-   *
-   * @param bottom the position that the bottom edge is dragged to
-   * @param bounds the bounding box of the image that is being cropped
-   * @param viewHeight
-   * @param snapMargin the snap distance to the image edge (in pixels)
-   */
-  private void adjustBottom(
-      RectF rect,
-      float bottom,
-      RectF bounds,
-      int viewHeight,
-      float snapMargin,
-      float aspectRatio,
-      boolean leftMoves,
-      boolean rightMoves) {
-
-    float newBottom = bottom;
-
-    if (newBottom > viewHeight) {
-      newBottom = viewHeight + (newBottom - viewHeight) / 1.05f;
-      mTouchOffset.y -= (newBottom - viewHeight) / 1.1f;
-    }
-
-    if (newBottom > bounds.bottom) {
-      mTouchOffset.y -= (newBottom - bounds.bottom) / 2f;
-    }
-
-    if (bounds.bottom - newBottom < snapMargin) {
-      newBottom = bounds.bottom;
-    }
-
-    // Checks if the window is too small vertically
-    if (newBottom - rect.top < mMinCropHeight) {
-      newBottom = rect.top + mMinCropHeight;
-    }
-
-    // Checks if the window is too small vertically
-    if (newBottom - rect.top > mMaxCropHeight) {
-      newBottom = rect.top + mMaxCropHeight;
-    }
-
-    if (bounds.bottom - newBottom < snapMargin) {
-      newBottom = bounds.bottom;
-    }
-
-    // check horizontal bounds if aspect ratio is in play
-    if (aspectRatio > 0) {
-      float newWidth = (newBottom - rect.top) * aspectRatio;
-
-      // Checks if the window is too small horizontally
-      if (newWidth < mMinCropWidth) {
-        newBottom = Math.min(bounds.bottom, rect.top + mMinCropWidth / aspectRatio);
-        newWidth = (newBottom - rect.top) * aspectRatio;
-      }
-
-      // Checks if the window is too large horizontally
-      if (newWidth > mMaxCropWidth) {
-        newBottom = Math.min(bounds.bottom, rect.top + mMaxCropWidth / aspectRatio);
-        newWidth = (newBottom - rect.top) * aspectRatio;
-      }
-
-      // if left AND right edge moves by aspect ratio check that it is within full width bounds
-      if (leftMoves && rightMoves) {
-        newBottom =
-            Math.min(newBottom, Math.min(bounds.bottom, rect.top + bounds.width() / aspectRatio));
-      } else {
-        // if left edge moves by aspect ratio check that it is within bounds
-        if (leftMoves && rect.right - newWidth < bounds.left) {
-          newBottom = Math.min(bounds.bottom, rect.top + (rect.right - bounds.left) / aspectRatio);
-          newWidth = (newBottom - rect.top) * aspectRatio;
-        }
-
-        // if right edge moves by aspect ratio check that it is within bounds
-        if (rightMoves && rect.left + newWidth > bounds.right) {
-          newBottom =
-              Math.min(
-                  newBottom,
-                  Math.min(bounds.bottom, rect.top + (bounds.right - rect.left) / aspectRatio));
-        }
-      }
-    }
-
-    rect.bottom = newBottom;
-  }
-
-  /**
-   * Adjust left edge by current crop window height and the given aspect ratio, the right edge
-   * remains in possition while the left adjusts to keep aspect ratio to the height.
-   */
-  private void adjustLeftByAspectRatio(RectF rect, float aspectRatio) {
-    rect.left = rect.right - rect.height() * aspectRatio;
-  }
-
-  /**
-   * Adjust top edge by current crop window width and the given aspect ratio, the bottom edge
-   * remains in possition while the top adjusts to keep aspect ratio to the width.
-   */
-  private void adjustTopByAspectRatio(RectF rect, float aspectRatio) {
-    rect.top = rect.bottom - rect.width() / aspectRatio;
-  }
-
-  /**
-   * Adjust right edge by current crop window height and the given aspect ratio, the left edge
-   * remains in possition while the left adjusts to keep aspect ratio to the height.
-   */
-  private void adjustRightByAspectRatio(RectF rect, float aspectRatio) {
-    rect.right = rect.left + rect.height() * aspectRatio;
-  }
-
-  /**
-   * Adjust bottom edge by current crop window width and the given aspect ratio, the top edge
-   * remains in possition while the top adjusts to keep aspect ratio to the width.
-   */
-  private void adjustBottomByAspectRatio(RectF rect, float aspectRatio) {
-    rect.bottom = rect.top + rect.width() / aspectRatio;
-  }
-
-  /**
-   * Adjust left and right edges by current crop window height and the given aspect ratio, both
-   * right and left edges adjusts equally relative to center to keep aspect ratio to the height.
-   */
-  private void adjustLeftRightByAspectRatio(RectF rect, RectF bounds, float aspectRatio) {
-    rect.inset((rect.width() - rect.height() * aspectRatio) / 2, 0);
-    if (rect.left < bounds.left) {
-      rect.offset(bounds.left - rect.left, 0);
-    }
-    if (rect.right > bounds.right) {
-      rect.offset(bounds.right - rect.right, 0);
-    }
-  }
-
-  /**
-   * Adjust top and bottom edges by current crop window width and the given aspect ratio, both top
-   * and bottom edges adjusts equally relative to center to keep aspect ratio to the width.
-   */
-  private void adjustTopBottomByAspectRatio(RectF rect, RectF bounds, float aspectRatio) {
-    rect.inset(0, (rect.height() - rect.width() / aspectRatio) / 2);
-    if (rect.top < bounds.top) {
-      rect.offset(0, bounds.top - rect.top);
-    }
-    if (rect.bottom > bounds.bottom) {
-      rect.offset(0, bounds.bottom - rect.bottom);
-    }
-  }
-
-  /** Calculates the aspect ratio given a rectangle. */
-  private static float calculateAspectRatio(float left, float top, float right, float bottom) {
-    return (right - left) / (bottom - top);
-  }
-  // endregion
-
-  // region: Inner class: Type
-
-  /** The type of crop window move that is handled. */
-  public enum Type {
-    TOP_LEFT,
-    TOP_RIGHT,
-    BOTTOM_LEFT,
-    BOTTOM_RIGHT,
-    LEFT,
-    TOP,
-    RIGHT,
-    BOTTOM,
-    CENTER
-  }
-  // endregion
-}

BIN
app/src/main/res/drawable-xxhdpi/crop_image_menu_flip.png


BIN
app/src/main/res/drawable-xxhdpi/crop_image_menu_rotate_left.png


BIN
app/src/main/res/drawable-xxhdpi/crop_image_menu_rotate_right.png


+ 1 - 1
app/src/main/res/layout/activity_camera.xml

@@ -48,7 +48,7 @@
 
 
              <!--灰色遮罩-->
-             <com.miekir.ocr.view.PhotoCropView
+             <com.miekir.ocr.view.CropView
                  android:id="@+id/pcv_scan"
                  android:layout_width="match_parent"
                  android:layout_height="0dp"

+ 0 - 7
app/src/main/res/layout/activity_main.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/activity_main"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -10,12 +9,6 @@
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="50dp"/>
-    <com.miekir.ocr.view.cropper.CropImageView
-        android:id="@+id/cropImageView"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="4"
-        app:cropAutoZoomEnabled="false"/>
 
     <FrameLayout
         android:layout_width="match_parent"

+ 0 - 6
app/src/main/res/layout/crop_image_activity.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.miekir.ocr.view.cropper.CropImageView
-    android:id="@+id/cropImageView"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"/>

+ 0 - 27
app/src/main/res/layout/crop_image_view.xml

@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
-       xmlns:tools="http://schemas.android.com/tools">
-
-    <ImageView
-        android:id="@+id/ImageView_image"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:adjustViewBounds="true"
-        android:scaleType="centerInside"
-        tools:ignore="contentDescription"/>
-    <!--android:adjustViewBounds="true"
-    android:scaleType="centerInside"-->
-
-    <com.miekir.ocr.view.cropper.CropOverlayView
-        android:id="@+id/CropOverlayView"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="invisible"/>
-
-    <ProgressBar
-        android:id="@+id/CropProgressBar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"/>
-
-</merge>

+ 2 - 2
app/src/main/res/layout/view_crop.xml

@@ -4,7 +4,7 @@
     android:layout_height="match_parent"
     android:orientation="vertical">
     <!--灰色遮罩-->
-    <com.miekir.ocr.view.rect.CustomLayout
+    <com.miekir.ocr.view.crop.CropLayout
         android:id="@+id/layout"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -16,5 +16,5 @@
             android:layout_width="200dp"
             android:layout_height="200dp" />
 
-    </com.miekir.ocr.view.rect.CustomLayout>
+    </com.miekir.ocr.view.crop.CropLayout>
 </LinearLayout>

+ 0 - 35
app/src/main/res/menu/crop_image_menu.xml

@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-      xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <item
-        android:id="@+id/crop_image_menu_rotate_left"
-        android:icon="@drawable/crop_image_menu_rotate_left"
-        android:title="@string/crop_image_menu_rotate_left"
-        android:visible="false"
-        app:showAsAction="ifRoom"/>
-    <item
-        android:id="@+id/crop_image_menu_rotate_right"
-        android:icon="@drawable/crop_image_menu_rotate_right"
-        android:title="@string/crop_image_menu_rotate_right"
-        app:showAsAction="ifRoom"/>
-    <item
-        android:id="@+id/crop_image_menu_flip"
-        android:icon="@drawable/crop_image_menu_flip"
-        android:title="@string/crop_image_menu_flip"
-        app:showAsAction="ifRoom">
-        <menu>
-            <item
-                android:id="@+id/crop_image_menu_flip_horizontally"
-                android:title="@string/crop_image_menu_flip_horizontally"/>
-            <item
-                android:id="@+id/crop_image_menu_flip_vertically"
-                android:title="@string/crop_image_menu_flip_vertically"/>
-        </menu>
-    </item>
-    <item
-        android:id="@+id/crop_image_menu_crop"
-        android:title="@string/crop_image_menu_crop"
-        app:showAsAction="always"/>
-
-</menu>

+ 1 - 11
app/src/main/res/values/strings.xml

@@ -2,15 +2,5 @@
     <string name="app_name">NRI AIOCR</string>
 
 
-    <!--裁剪类库开始-->
-    <string name="crop_image_activity_title">Crop</string>
-    <string name="crop_image_menu_rotate_left">Rotate counter clockwise</string>
-    <string name="crop_image_menu_rotate_right">Rotate</string>
-    <string name="crop_image_menu_crop">Crop</string>
-    <string name="crop_image_menu_flip">Flip</string>
-    <string name="crop_image_menu_flip_horizontally">Flip horizontally</string>
-    <string name="crop_image_menu_flip_vertically">Flip vertically</string>
-    <string name="pick_image_intent_chooser_title">Select source</string>
-    <string name="crop_image_activity_no_permissions">Cancelling, required permissions are not granted</string>
-    <!--裁剪类库结束-->
+
 </resources>

+ 0 - 27
common/src/androidTest/java/com/genlot/common/ExampleInstrumentedTest.java

@@ -1,27 +0,0 @@
-package com.genlot.common;
-
-import android.content.Context;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
-    @Test
-    public void useAppContext() {
-        // Context of the app under test.
-        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-
-        assertEquals("com.genlot.common.test", appContext.getPackageName());
-    }
-}

+ 1 - 4
common/src/androidTest/java/com/miekir/common/ExampleInstrumentedTest.java

@@ -2,14 +2,12 @@ package com.miekir.common;
 
 import android.content.Context;
 
-import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import static org.junit.Assert.*;
-
 /**
  * Instrumented test, which will execute on an Android device.
  *
@@ -22,6 +20,5 @@ public class ExampleInstrumentedTest {
         // Context of the app under test.
         Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
 
-        assertEquals("com.genlot.common.test", appContext.getPackageName());
     }
 }

+ 0 - 17
common/src/test/java/com/genlot/common/ExampleUnitTest.java

@@ -1,17 +0,0 @@
-package com.genlot.common;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
- */
-public class ExampleUnitTest {
-    @Test
-    public void addition_isCorrect() {
-        assertEquals(4, 2 + 2);
-    }
-}

+ 0 - 27
network/src/androidTest/java/com/genlot/network/ExampleInstrumentedTest.java

@@ -1,27 +0,0 @@
-package com.genlot.network;
-
-import android.content.Context;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
-    @Test
-    public void useAppContext() {
-        // Context of the app under test.
-        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-
-        assertEquals("com.genlot.network.test", appContext.getPackageName());
-    }
-}

+ 1 - 4
network/src/androidTest/java/com/miekir/network/ExampleInstrumentedTest.java

@@ -2,14 +2,12 @@ package com.miekir.network;
 
 import android.content.Context;
 
-import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import static org.junit.Assert.*;
-
 /**
  * Instrumented test, which will execute on an Android device.
  *
@@ -22,6 +20,5 @@ public class ExampleInstrumentedTest {
         // Context of the app under test.
         Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
 
-        assertEquals("com.genlot.network.test", appContext.getPackageName());
     }
 }

+ 0 - 17
network/src/test/java/com/genlot/network/ExampleUnitTest.java

@@ -1,17 +0,0 @@
-package com.genlot.network;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
- */
-public class ExampleUnitTest {
-    @Test
-    public void addition_isCorrect() {
-        assertEquals(4, 2 + 2);
-    }
-}