diff options
Diffstat (limited to 'cropper/src/main/java/com')
11 files changed, 0 insertions, 8137 deletions
diff --git a/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapCroppingWorkerTask.java b/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapCroppingWorkerTask.java deleted file mode 100644 index 54d33df4e..000000000 --- a/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapCroppingWorkerTask.java +++ /dev/null @@ -1,354 +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.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 BitmapCroppingWorkerTask.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 -} diff --git a/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapLoadingWorkerTask.java b/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapLoadingWorkerTask.java deleted file mode 100644 index a6ecf9396..000000000 --- a/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapLoadingWorkerTask.java +++ /dev/null @@ -1,176 +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.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 -} diff --git a/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapUtils.java b/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapUtils.java deleted file mode 100644 index 7190bd429..000000000 --- a/cropper/src/main/java/com/theartofdev/edmodo/cropper/BitmapUtils.java +++ /dev/null @@ -1,923 +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.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 androidx.exifinterface.media.ExifInterface; - -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; - -/** - * 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 save bitmaps during state save and restore so not to reload them. - */ - static Pair<String, WeakReference<Bitmap>> mStateBitmap; - /** - * Used to know the max texture size allowed to be rendered - */ - private static int mMaxTextureSize; - - /** - * 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);< |