summaryrefslogtreecommitdiffstats
path: root/cropper/src/main/java/com/theartofdev/edmodo/cropper/CropImageView.java
diff options
context:
space:
mode:
Diffstat (limited to 'cropper/src/main/java/com/theartofdev/edmodo/cropper/CropImageView.java')
-rw-r--r--cropper/src/main/java/com/theartofdev/edmodo/cropper/CropImageView.java2296
1 files changed, 0 insertions, 2296 deletions
diff --git a/cropper/src/main/java/com/theartofdev/edmodo/cropper/CropImageView.java b/cropper/src/main/java/com/theartofdev/edmodo/cropper/CropImageView.java
deleted file mode 100644
index 2e835b070..000000000
--- a/cropper/src/main/java/com/theartofdev/edmodo/cropper/CropImageView.java
+++ /dev/null
@@ -1,2296 +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.theartofdev.edmodo.cropper;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-
-import androidx.exifinterface.media.ExifInterface;
-
-import java.lang.ref.WeakReference;
-import java.util.UUID;
-
-/**
- * Custom view that provides cropping capabilities to an image.
- */
-public class CropImageView extends FrameLayout {
-
- // region: Fields and Consts
-
- /**
- * Image view widget used to show the image for cropping.
- */
- private final ImageView mImageView;
-
- /**
- * Overlay over the image view to show cropping UI.
- */
- private final CropOverlayView mCropOverlayView;
-
- /**
- * The matrix used to transform the cropping image in the image view
- */
- private final Matrix mImageMatrix = new Matrix();
-
- /**
- * Reusing matrix instance for reverse matrix calculations.
- */
- private final Matrix mImageInverseMatrix = new Matrix();
-
- /**
- * Progress bar widget to show progress bar on async image loading and cropping.
- */
- private final ProgressBar mProgressBar;
-
- /**
- * Rectangle used in image matrix transformation calculation (reusing rect instance)
- */
- private final float[] mImagePoints = new float[8];
-
- /**
- * Rectangle used in image matrix transformation for scale calculation (reusing rect instance)
- */
- private final float[] mScaleImagePoints = new float[8];
-
- /**
- * Animation class to smooth animate zoom-in/out
- */
- private CropImageAnimation mAnimation;
-
- private Bitmap mBitmap;
-
- /**
- * The image rotation value used during loading of the image so we can reset to it
- */
- private int mInitialDegreesRotated;
-
- /**
- * How much the image is rotated from original clockwise
- */
- private int mDegreesRotated;
-
- /**
- * if the image flipped horizontally
- */
- private boolean mFlipHorizontally;
-
- /**
- * if the image flipped vertically
- */
- private boolean mFlipVertically;
-
- private int mLayoutWidth;
-
- private int mLayoutHeight;
-
- private int mImageResource;
-
- /**
- * The initial scale type of the image in the crop image view
- */
- private ScaleType mScaleType;
-
- /**
- * if to save bitmap on save instance state.<br>
- * It is best to avoid it by using URI in setting image for cropping.<br>
- * If false the bitmap is not saved and if restore is required to view will be empty, storing the
- * bitmap requires saving it to file which can be expensive. default: false.
- */
- private boolean mSaveBitmapToInstanceState = false;
-
- /**
- * 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.
- */
- private boolean mShowCropOverlay = true;
-
- /**
- * if to show progress bar when image async loading/cropping is in progress.<br>
- * default: true, disable to provide custom progress bar UI.
- */
- private boolean mShowProgressBar = true;
-
- /**
- * if auto-zoom functionality is enabled.<br>
- * default: true.
- */
- private boolean mAutoZoomEnabled = true;
-
- /**
- * The max zoom allowed during cropping
- */
- private int mMaxZoom;
-
- /**
- * callback to be invoked when crop overlay is released.
- */
- private OnSetCropOverlayReleasedListener mOnCropOverlayReleasedListener;
-
- /**
- * callback to be invoked when crop overlay is moved.
- */
- private OnSetCropOverlayMovedListener mOnSetCropOverlayMovedListener;
-
- /**
- * callback to be invoked when crop window is changed.
- */
- private OnSetCropWindowChangeListener mOnSetCropWindowChangeListener;
-
- /**
- * callback to be invoked when image async loading is complete.
- */
- private OnSetImageUriCompleteListener mOnSetImageUriCompleteListener;
-
- /**
- * callback to be invoked when image async cropping is complete.
- */
- private OnCropImageCompleteListener mOnCropImageCompleteListener;
-
- /**
- * The URI that the image was loaded from (if loaded from URI)
- */
- private Uri mLoadedImageUri;
-
- /**
- * The sample size the image was loaded by if was loaded by URI
- */
- private int mLoadedSampleSize = 1;
-
- /**
- * The current zoom level to to scale the cropping image
- */
- private float mZoom = 1;
-
- /**
- * The X offset that the cropping image was translated after zooming
- */
- private float mZoomOffsetX;
-
- /**
- * The Y offset that the cropping image was translated after zooming
- */
- private float mZoomOffsetY;
-
- /**
- * Used to restore the cropping windows rectangle after state restore
- */
- private RectF mRestoreCropWindowRect;
-
- /**
- * Used to restore image rotation after state restore
- */
- private int mRestoreDegreesRotated;
-
- /**
- * Used to detect size change to handle auto-zoom using {@link #handleCropWindowChanged(boolean,
- * boolean)} in {@link #layout(int, int, int, int)}.
- */
- private boolean mSizeChanged;
-
- /**
- * Temp URI used to save bitmap image to disk to preserve for instance state in case cropped was
- * set with bitmap
- */
- private Uri mSaveInstanceStateBitmapUri;
-
- /**
- * Task used to load bitmap async from UI thread
- */
- private WeakReference<BitmapLoadingWorkerTask> mBitmapLoadingWorkerTask;
-
- /**
- * Task used to crop bitmap async from UI thread
- */
- private WeakReference<BitmapCroppingWorkerTask> mBitmapCroppingWorkerTask;
- // endregion
-
- public CropImageView(Context context) {
- this(context, null);
- }
-
- public CropImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- CropImageOptions options = null;
- Intent intent = context instanceof Activity ? ((Activity) context).getIntent() : null;
- if (intent != null) {
- Bundle bundle = intent.getBundleExtra(CropImage.CROP_IMAGE_EXTRA_BUNDLE);
- if (bundle != null) {
- options = bundle.getParcelable(CropImage.CROP_IMAGE_EXTRA_OPTIONS);
- }
- }
-
- if (options == null) {
-
- options = new CropImageOptions();
-
- if (attrs != null) {
- TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CropImageView, 0, 0);
- try {
- options.fixAspectRatio =
- ta.getBoolean(R.styleable.CropImageView_cropFixAspectRatio, options.fixAspectRatio);
- options.aspectRatioX =
- ta.getInteger(R.styleable.CropImageView_cropAspectRatioX, options.aspectRatioX);
- options.aspectRatioY =
- ta.getInteger(R.styleable.CropImageView_cropAspectRatioY, options.aspectRatioY);
- options.scaleType =
- ScaleType.values()[
- ta.getInt(R.styleable.CropImageView_cropScaleType, options.scaleType.ordinal())];
- options.autoZoomEnabled =
- ta.getBoolean(R.styleable.CropImageView_cropAutoZoomEnabled, options.autoZoomEnabled);
- options.multiTouchEnabled =
- ta.getBoolean(
- R.styleable.CropImageView_cropMultiTouchEnabled, options.multiTouchEnabled);
- options.maxZoom = ta.getInteger(R.styleable.CropImageView_cropMaxZoom, options.maxZoom);
- options.cropShape =
- CropShape.values()[
- ta.getInt(R.styleable.CropImageView_cropShape, options.cropShape.ordinal())];
- options.guidelines =
- Guidelines.values()[
- ta.getInt(
- R.styleable.CropImageView_cropGuidelines, options.guidelines.ordinal())];
- options.snapRadius =
- ta.getDimension(R.styleable.CropImageView_cropSnapRadius, options.snapRadius);
- options.touchRadius =
- ta.getDimension(R.styleable.CropImageView_cropTouchRadius, options.touchRadius);
- options.initialCropWindowPaddingRatio =
- ta.getFloat(
- R.styleable.CropImageView_cropInitialCropWindowPaddingRatio,
- options.initialCropWindowPaddingRatio);
- options.borderLineThickness =
- ta.getDimension(
- R.styleable.CropImageView_cropBorderLineThickness, options.borderLineThickness);
- options.borderLineColor =
- ta.getInteger(R.styleable.CropImageView_cropBorderLineColor, options.borderLineColor);
- options.borderCornerThickness =
- ta.getDimension(
- R.styleable.CropImageView_cropBorderCornerThickness,
- options.borderCornerThickness);
- options.borderCornerOffset =
- ta.getDimension(
- R.styleable.CropImageView_cropBorderCornerOffset, options.borderCornerOffset);
- options.borderCornerLength =
- ta.getDimension(
- R.styleable.CropImageView_cropBorderCornerLength, options.borderCornerLength);
- options.borderCornerColor =
- ta.getInteger(
- R.styleable.CropImageView_cropBorderCornerColor, options.borderCornerColor);
- options.guidelinesThickness =
- ta.getDimension(
- R.styleable.CropImageView_cropGuidelinesThickness, options.guidelinesThickness);
- options.guidelinesColor =
- ta.getInteger(R.styleable.CropImageView_cropGuidelinesColor, options.guidelinesColor);
- options.backgroundColor =
- ta.getInteger(R.styleable.CropImageView_cropBackgroundColor, options.backgroundColor);
- options.showCropOverlay =
- ta.getBoolean(R.styleable.CropImageView_cropShowCropOverlay, mShowCropOverlay);
- options.showProgressBar =
- ta.getBoolean(R.styleable.CropImageView_cropShowProgressBar, mShowProgressBar);
- options.borderCornerThickness =
- ta.getDimension(
- R.styleable.CropImageView_cropBorderCornerThickness,
- options.borderCornerThickness);
- options.minCropWindowWidth =
- (int)
- ta.getDimension(
- R.styleable.CropImageView_cropMinCropWindowWidth, options.minCropWindowWidth);
- options.minCropWindowHeight =
- (int)
- ta.getDimension(
- R.styleable.CropImageView_cropMinCropWindowHeight,
- options.minCropWindowHeight);
- options.minCropResultWidth =
- (int)
- ta.getFloat(
- R.styleable.CropImageView_cropMinCropResultWidthPX,
- options.minCropResultWidth);
- options.minCropResultHeight =
- (int)
- ta.getFloat(
- R.styleable.CropImageView_cropMinCropResultHeightPX,
- options.minCropResultHeight);
- options.maxCropResultWidth =
- (int)
- ta.getFloat(
- R.styleable.CropImageView_cropMaxCropResultWidthPX,
- options.maxCropResultWidth);
- options.maxCropResultHeight =
- (int)
- ta.getFloat(
- R.styleable.CropImageView_cropMaxCropResultHeightPX,
- options.maxCropResultHeight);
- options.flipHorizontally =
- ta.getBoolean(
- R.styleable.CropImageView_cropFlipHorizontally, options.flipHorizontally);
- options.flipVertically =
- ta.getBoolean(R.styleable.CropImageView_cropFlipHorizontally, options.flipVertically);
-
- mSaveBitmapToInstanceState =
- ta.getBoolean(
- R.styleable.CropImageView_cropSaveBitmapToInstanceState,
- mSaveBitmapToInstanceState);
-
- // if aspect ratio is set then set fixed to true
- if (ta.hasValue(R.styleable.CropImageView_cropAspectRatioX)
- && ta.hasValue(R.styleable.CropImageView_cropAspectRatioX)
- && !ta.hasValue(R.styleable.CropImageView_cropFixAspectRatio)) {
- options.fixAspectRatio = true;
- }
- } finally {
- ta.recycle();
- }
- }
- }
-
- options.validate();
-
- mScaleType = options.scaleType;
- mAutoZoomEnabled = options.autoZoomEnabled;
- mMaxZoom = options.maxZoom;
- mShowCropOverlay = options.showCropOverlay;
- mShowProgressBar = options.showProgressBar;
- mFlipHorizontally = options.flipHorizontally;
- mFlipVertically = options.flipVertically;
-
- LayoutInflater inflater = LayoutInflater.from(context);
- View v = inflater.inflate(R.layout.crop_image_view, this, true);
-
- mImageView = v.findViewById(R.id.ImageView_image);
- mImageView.setScaleType(ImageView.ScaleType.MATRIX);
-
- mCropOverlayView = v.findViewById(R.id.CropOverlayView);
- mCropOverlayView.setCropWindowChangeListener(
- new CropOverlayView.CropWindowChangeListener() {
- @Override
- public void onCropWindowChanged(boolean inProgress) {
- handleCropWindowChanged(inProgress, true);
- OnSetCropOverlayReleasedListener listener = mOnCropOverlayReleasedListener;
- if (listener != null && !inProgress) {
- listener.onCropOverlayReleased(getCropRect());
- }
- OnSetCropOverlayMovedListener movedListener = mOnSetCropOverlayMovedListener;
- if (movedListener != null && inProgress) {
- movedListener.onCropOverlayMoved(getCropRect());
- }
- }
- });
- mCropOverlayView.setInitialAttributeValues(options);
-
- mProgressBar = v.findViewById(R.id.CropProgressBar);
- setProgressBarVisibility();
- }
-
- /**
- * Determines the specs for the onMeasure function. Calculates the width or height depending on
- * the mode.
- *
- * @param measureSpecMode The mode of the measured width or height.
- * @param measureSpecSize The size of the measured width or height.
- * @param desiredSize The desired size of the measured width or height.
- * @return The final size of the width or height.
- */
- private static int getOnMeasureSpec(int measureSpecMode, int measureSpecSize, int desiredSize) {
-
- // Measure Width
- int spec;
- if (measureSpecMode == MeasureSpec.EXACTLY) {
- // Must be this size
- spec = measureSpecSize;
- } else if (measureSpecMode == MeasureSpec.AT_MOST) {
- // Can't be bigger than...; match_parent value
- spec = Math.min(desiredSize, measureSpecSize);
- } else {
- // Be whatever you want; wrap_content
- spec = desiredSize;
- }
-
- return spec;
- }
-
- /**
- * Get the scale type of the image in the crop view.
- */
- public ScaleType getScaleType() {
- return mScaleType;
- }
-
- /**
- * Set the scale type of the image in the crop view
- */
- public void setScaleType(ScaleType scaleType) {
- if (scaleType != mScaleType) {
- mScaleType = scaleType;
- mZoom = 1;
- mZoomOffsetX = mZoomOffsetY = 0;
- mCropOverlayView.resetCropOverlayView();
- requestLayout();
- }
- }
-
- /**
- * The shape of the cropping area - rectangle/circular.
- */
- public CropShape getCropShape() {
- return mCropOverlayView.getCropShape();
- }
-
- /**
- * The shape of the cropping area - rectangle/circular.<br>
- * To set square/circle crop shape set aspect ratio to 1:1.
- */
- public void setCropShape(CropShape cropShape) {
- mCropOverlayView.setCropShape(cropShape);
- }
-
- /**
- * if auto-zoom functionality is enabled. default: true.
- */
- public boolean isAutoZoomEnabled() {
- return mAutoZoomEnabled;
- }
-
- /**
- * Set auto-zoom functionality to enabled/disabled.
- */
- public void setAutoZoomEnabled(boolean autoZoomEnabled) {
- if (mAutoZoomEnabled != autoZoomEnabled) {
- mAutoZoomEnabled = autoZoomEnabled;
- handleCropWindowChanged(false, false);
- mCropOverlayView.invalidate();
- }
- }
-
- /**
- * Set multi touch functionality to enabled/disabled.
- */
- public void setMultiTouchEnabled(boolean multiTouchEnabled) {
- if (mCropOverlayView.setMultiTouchEnabled(multiTouchEnabled)) {
- handleCropWindowChanged(false, false);
- mCropOverlayView.invalidate();
- }
- }
-
- /**
- * The max zoom allowed during cropping.
- */
- public int getMaxZoom() {
- return mMaxZoom;
- }
-
- /**
- * The max zoom allowed during cropping.
- */
- public void setMaxZoom(int maxZoom) {
- if (mMaxZoom != maxZoom && maxZoom > 0) {
- mMaxZoom = maxZoom;
- handleCropWindowChanged(false, false);
- mCropOverlayView.invalidate();
- }
- }
-
- /**
- * 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) {
- mCropOverlayView.setMinCropResultSize(minCropResultWidth, 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) {
- mCropOverlayView.setMaxCropResultSize(maxCropResultWidth, maxCropResultHeight);
- }
-
- /**
- * Get the amount of degrees the cropping image is rotated cloackwise.<br>
- *
- * @return 0-360
- */
- public int getRotatedDegrees() {
- return mDegreesRotated;
- }
-
- /**
- * Set the amount of degrees the cropping image is rotated cloackwise.<br>
- *
- * @param degrees 0-360
- */
- public void setRotatedDegrees(int degrees) {
- if (mDegreesRotated != degrees) {
- rotateImage(degrees - mDegreesRotated);
- }
- }
-
- /**
- * whether the aspect ratio is fixed or not; true fixes the aspect ratio, while false allows it to
- * be changed.
- */
- public boolean isFixAspectRatio() {
- return mCropOverlayView.isFixAspectRatio();
- }
-
- /**
- * Sets whether the aspect ratio is fixed or not; true fixes the aspect ratio, while false allows
- * it to be changed.
- */
- public void setFixedAspectRatio(boolean fixAspectRatio) {
- mCropOverlayView.setFixedAspectRatio(fixAspectRatio);
- }
-
- /**
- * whether the image should be flipped horizontally
- */
- public boolean isFlippedHorizontally() {
- return mFlipHorizontally;
- }
-
- /**
- * Sets whether the image should be flipped horizontally
- */
- public void setFlippedHorizontally(boolean flipHorizontally) {
- if (mFlipHorizontally != flipHorizontally) {
- mFlipHorizontally = flipHorizontally;
- applyImageMatrix(getWidth(), getHeight(), true, false);
- }
- }
-
- /**
- * whether the image should be flipped vertically
- */
- public boolean isFlippedVertically() {
- return mFlipVertically;
- }
-
- /**
- * Sets whether the image should be flipped vertically
- */
- public void setFlippedVertically(boolean flipVertically) {
- if (mFlipVertically != flipVertically) {
- mFlipVertically = flipVertically;
- applyImageMatrix(getWidth(), getHeight(), true, false);
- }
- }
-
- /**
- * Get the current guidelines option set.
- */
- public Guidelines getGuidelines() {
- return mCropOverlayView.getGuidelines();
- }
-
- /**
- * Sets the guidelines for the CropOverlayView to be either on, off, or to show when resizing the
- * application.
- */
- public void setGuidelines(Guidelines guidelines) {
- mCropOverlayView.setGuidelines(guidelines);
- }
-
- /**
- * both the X and Y values of the aspectRatio.
- */
- public Pair<Integer, Integer> getAspectRatio() {
- return new Pair<>(mCropOverlayView.getAspectRatioX(), mCropOverlayView.getAspectRatioY());
- }
-
- /**
- * Sets the both the X and Y values of the aspectRatio.<br>
- * Sets fixed aspect ratio to TRUE.
- *
- * @param aspectRatioX int that specifies the new X value of the aspect ratio
- * @param aspectRatioY int that specifies the new Y value of the aspect ratio
- */
- public void setAspectRatio(int aspectRatioX, int aspectRatioY) {
- mCropOverlayView.setAspectRatioX(aspectRatioX);
- mCropOverlayView.setAspectRatioY(aspectRatioY);
- setFixedAspectRatio(true);
- }
-
- /**
- * Clears set aspect ratio values and sets fixed aspect ratio to FALSE.
- */
- public void clearAspectRatio() {
- mCropOverlayView.setAspectRatioX(1);
- mCropOverlayView.setAspectRatioY(1);
- setFixedAspectRatio(false);
- }
-
- /**
- * 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. (default: 3dp)
- */
- public void setSnapRadius(float snapRadius) {
- if (snapRadius >= 0) {
- mCropOverlayView.setSnapRadius(snapRadius);
- }
- }
-
- /**
- * 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 isShowProgressBar() {
- return mShowProgressBar;
- }
-
- /**
- * if to show progress bar when image async loading/cropping is in progress.<br>
- * default: true, disable to provide custom progress bar UI.
- */
- public void setShowProgressBar(boolean showProgressBar) {
- if (mShowProgressBar != showProgressBar) {
- mShowProgressBar = showProgressBar;
- setProgressBarVisibility();
- }
- }
-
- /**
- * 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 isShowCropOverlay() {
- return mShowCropOverlay;
- }
-
- /**
- * 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 void setShowCropOverlay(boolean showCropOverlay) {
- if (mShowCropOverlay != showCropOverlay) {
- mShowCropOverlay = showCropOverlay;
- setCropOverlayVisibility();
- }
- }
-
- /**
- * if to save bitmap on save instance state.<br>
- * It is best to avoid it by using URI in setting image for cropping.<br>
- * If false the bitmap is not saved and if restore is required to view will be empty, storing the
- * bitmap requires saving it to file which can be expensive. default: false.
- */
- public boolean isSaveBitmapToInstanceState() {
- return mSaveBitmapToInstanceState;
- }
-
- /**
- * if to save bitmap on save instance state.<br>
- * It is best to avoid it by using URI in setting image for cropping.<br>
- * If false the bitmap is not saved and if restore is required to view will be empty, storing the
- * bitmap requires saving it to file which can be expensive. default: false.
- */
- public void setSaveBitmapToInstanceState(boolean saveBitmapToInstanceState) {
- mSaveBitmapToInstanceState = saveBitmapToInstanceState;
- }
-
- /**
- * Returns the integer of the imageResource
- */
- public int getImageResource() {
- return mImageResource;
- }
-
- /**
- * Sets a Drawable as the content of the CropImageView.
- *
- * @param resId the drawable resource ID to set
- */
- public void setImageResource(int resId) {
- if (resId != 0) {
- mCropOverlayView.setInitialCropWindowRect(null);
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
- setBitmap(bitmap, resId, null, 1, 0);
- }
- }
-
- /**
- * Get the URI of an image that was set by URI, null otherwise.
- */
- public Uri getImageUri() {
- return mLoadedImageUri;
- }
-
- /**
- * Gets the source Bitmap's dimensions. This represents the largest possible crop rectangle.
- *
- * @return a Rect instance dimensions of the source Bitmap
- */
- public Rect getWholeImageRect() {
- int loadedSampleSize = mLoadedSampleSize;
- Bitmap bitmap = mBitmap;
- if (bitmap == null) {
- return null;
- }
-
- int orgWidth = bitmap.getWidth() * loadedSampleSize;
- int orgHeight = bitmap.getHeight() * loadedSampleSize;
- return new Rect(0, 0, orgWidth, orgHeight);
- }
-
- /**
- * Gets the crop window's position relative to the source Bitmap (not the image displayed in the
- * CropImageView) using the original image rotation.
- *
- * @return a Rect instance containing cropped area boundaries of the source Bitmap
- */
- public Rect getCropRect() {
- int loadedSampleSize = mLoadedSampleSize;
- Bitmap bitmap = mBitmap;
- if (bitmap == null) {
- return null;
- }
-
- // get the points of the crop rectangle adjusted to source bitmap
- float[] points = getCropPoints();
-
- int orgWidth = bitmap.getWidth() * loadedSampleSize;
- int orgHeight = bitmap.getHeight() * loadedSampleSize;
-
- // get the rectangle for the points (it may be larger than original if rotation is not stright)
- return BitmapUtils.getRectFromPoints(
- points,
- orgWidth,
- orgHeight,
- mCropOverlayView.isFixAspectRatio(),
- mCropOverlayView.getAspectRatioX(),
- mCropOverlayView.getAspectRatioY());
- }
-
- /**
- * Set the crop window position and size to the given rectangle.<br>
- * Image to crop must be first set before invoking this, for async - after complete callback.
- *
- * @param rect window rectangle (position and size) relative to source bitmap
- */
- public void setCropRect(Rect rect) {
- mCropOverlayView.setInitialCropWindowRect(rect);
- }
-
- /**
- * Gets the crop window's position relative to the parent's view at screen.
- *
- * @return a Rect instance containing cropped area boundaries of the source Bitmap
- */
- public RectF getCropWindowRect() {
- if (mCropOverlayView == null) {
- return null;
- }
- return mCropOverlayView.getCropWindowRect();
- }
-
- /**
- * Gets the 4 points of crop window's position relative to the source Bitmap (not the image
- * displayed in the CropImageView) using the original image rotation.<br>
- * Note: the 4 points may not be a rectangle if the image was rotates to NOT stright angle (!=
- * 90/180/270).
- *
- * @return 4 points (x0,y0,x1,y1,x2,y2,x3,y3) of cropped area boundaries
- */
- public float[] getCropPoints() {
-
- // Get crop window position relative to the displayed image.
- RectF cropWindowRect = mCropOverlayView.getCropWindowRect();
-
- float[] points =
- new float[]{
- cropWindowRect.left,
- cropWindowRect.top,
- cropWindowRect.right,
- cropWindowRect.top,
- cropWindowRect.right,
- cropWindowRect.bottom,
- cropWindowRect.left,
- cropWindowRect.bottom
- };
-
- mImageMatrix.invert(mImageInverseMatrix);
- mImageInverseMatrix.mapPoints(points);
-
- for (int i = 0; i < points.length; i++) {
- points[i] *= mLoadedSampleSize;
- }
-
- return points;
- }
-
- /**
- * Reset crop window to initial rectangle.
- */
- public void resetCropRect() {
- mZoom = 1;
- mZoomOffsetX = 0;
- mZoomOffsetY = 0;
- mDegreesRotated = mInitialDegreesRotated;
- mFlipHorizontally = false;
- mFlipVertically = false;
- applyImageMatrix(getWidth(), getHeight(), false, false);
- mCropOverlayView.resetCropWindowRect();
- }
-
- /**
- * Gets the cropped image based on the current crop window.
- *
- * @return a new Bitmap representing the cropped image
- */
- public Bitmap getCroppedImage() {
- return getCroppedImage(0, 0, RequestSizeOptions.NONE);
- }
-
- /**
- * Gets the cropped image based on the current crop window.<br>
- * Uses {@link RequestSizeOptions#RESIZE_INSIDE} option.
- *
- * @param reqWidth the width to resize the cropped image to
- * @param reqHeight the height to resize the cropped image to
- * @return a new Bitmap representing the cropped image
- */
- public Bitmap getCroppedImage(int reqWidth, int reqHeight) {
- return getCroppedImage(reqWidth, reqHeight, RequestSizeOptions.RESIZE_INSIDE);
- }
-
- /**
- * Gets the cropped image based on the current crop window.<br>
- *
- * @param reqWidth the width to resize the cropped image to (see options)
- * @param reqHeight the height to resize the cropped image to (see options)
- * @param options the resize method to use, see its documentation
- * @return a new Bitmap representing the cropped image
- */
- public Bitmap getCroppedImage(int reqWidth, int reqHeight, RequestSizeOptions options) {
- Bitmap croppedBitmap = null;
- if (mBitmap != null) {
- mImageView.clearAnimation();
-
- reqWidth = options != RequestSizeOptions.NONE ? reqWidth : 0;
- reqHeight = options != RequestSizeOptions.NONE ? reqHeight : 0;
-
- if (mLoadedImageUri != null
- && (mLoadedSampleSize > 1 || options == RequestSizeOptions.SAMPLING)) {
- int orgWidth = mBitmap.getWidth() * mLoadedSampleSize;
- int orgHeight = mBitmap.getHeight() * mLoadedSampleSize;
- BitmapUtils.BitmapSampled bitmapSampled =
- BitmapUtils.cropBitmap(
- getContext(),
- mLoadedImageUri,
- getCropPoints(),
- mDegreesRotated,
- orgWidth,
- orgHeight,
- mCropOverlayView.isFixAspectRatio(),
- mCropOverlayView.getAspectRatioX(),
- mCropOverlayView.getAspectRatioY(),
- reqWidth,
- reqHeight,
- mFlipHorizontally,
- mFlipVertically);
- croppedBitmap = bitmapSampled.bitmap;
- } else {
- croppedBitmap =
- BitmapUtils.cropBitmapObjectHandleOOM(
- mBitmap,
- getCropPoints(),
- mDegreesRotated,
- mCropOverlayView.isFixAspectRatio(),
- mCropOverlayView.getAspectRatioX(),
- mCropOverlayView.getAspectRatioY(),
- mFlipHorizontally,
- mFlipVertically)
- .bitmap;
- }
-
- croppedBitmap = BitmapUtils.resizeBitmap(croppedBitmap, reqWidth, reqHeight, options);
- }
-
- return croppedBitmap;
- }
-
- /**
- * Gets the cropped image based on the current crop window.<br>
- * The result will be invoked to listener set by {@link
- * #setOnCropImageCompleteListener(OnCropImageCompleteListener)}.
- */
- public void getCroppedImageAsync() {
- getCroppedImageAsync(0, 0, RequestSizeOptions.NONE);
- }
-
- /**
- * Gets the cropped image based on the current crop window.<br>
- * Uses {@link RequestSizeOptions#RESIZE_INSIDE} option.<br>
- * The result will be invoked to listener set by {@link
- * #setOnCropImageCompleteListener(OnCropImageCompleteListener)}.
- *
- * @param reqWidth the width to resize the cropped image to
- * @param reqHeight the height to resize the cropped image to
- */
- public void getCroppedImageAsync(int reqWidth, int reqHeight) {
- getCroppedImageAsync(reqWidth, reqHeight, RequestSizeOptions.RESIZE_INSIDE);
- }
-
- /**
- * Gets the cropped image based on the current crop window.<br>
- * The result will be invoked to listener set by {@link
- * #setOnCropImageCompleteListener(OnCropImageCompleteListener)}.
- *
- * @param reqWidth the width to resize the cropped image to (see options)
- * @param reqHeight the height to resize the cropped image to (see options)
- * @param options the resize method to use, see its documentation
- */
- public void getCroppedImageAsync(int reqWidth, int reqHeight, RequestSizeOptions options) {
- if (mOnCropImageCompleteListener == null) {
- throw new IllegalArgumentException("mOnCropImageCompleteListener is not set");
- }
- startCropWorkerTask(reqWidth, reqHeight, options, null, null, 0);
- }
-
- /**
- * Save the cropped image based on the current crop window to the given uri.<br>
- * Uses JPEG image compression with 90 compression quality.<br>
- * The result will be invoked to listener set by {@link
- * #setOnCropImageCompleteListener(OnCropImageCompleteListener)}.
- *
- * @param saveUri the Android Uri to save the cropped image to
- */
- public void saveCroppedImageAsync(Uri saveUri) {
- saveCroppedImageAsync(saveUri, Bitmap.CompressFormat.JPEG, 90, 0, 0, RequestSizeOptions.NONE);
- }
-
- /**
- * Save the cropped image based on the current crop window to the given uri.<br>
- * The result will be invoked to listener set by {@link
- * #setOnCropImageCompleteListener(OnCropImageCompleteListener)}.
- *
- * @param saveUri the Android Uri to save the cropped image to
- * @param saveCompressFormat the compression format to use when writing the image
- * @param saveCompressQuality the quality (if applicable) to use when writing the image (0 - 100)
- */
- public void saveCroppedImageAsync(
-