diff options
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.java | 2296 |
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( - |