package com.yalantis.ucrop.util; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Point; import android.media.ExifInterface; import android.net.Uri; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; import android.view.Display; import android.view.WindowManager; import com.yalantis.ucrop.callback.BitmapLoadCallback; import com.yalantis.ucrop.task.BitmapLoadTask; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; /** * Created by Oleksii Shliama (https://github.com/shliama). */ public class BitmapLoadUtils { private static final String TAG = "BitmapLoadUtils"; public static void decodeBitmapInBackground(@NonNull Context context, @NonNull Uri uri, @Nullable Uri outputUri, int requiredWidth, int requiredHeight, BitmapLoadCallback loadCallback) { new BitmapLoadTask(context, uri, outputUri, requiredWidth, requiredHeight, loadCallback).execute(); } public static Bitmap transformBitmap(@NonNull Bitmap bitmap, @NonNull Matrix transformMatrix) { try { Bitmap converted = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), transformMatrix, true); if (!bitmap.sameAs(converted)) { bitmap = converted; } } catch (OutOfMemoryError error) { Log.e(TAG, "transformBitmap: ", error); } return bitmap; } public static int calculateInSampleSize(@NonNull BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width lower or equal to the requested height and width. while ((height / inSampleSize) > reqHeight || (width / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } public static int getExifOrientation(@NonNull Context context, @NonNull Uri imageUri) { int orientation = ExifInterface.ORIENTATION_UNDEFINED; try { InputStream stream = context.getContentResolver().openInputStream(imageUri); if (stream == null) { return orientation; } orientation = new ImageHeaderParser(stream).getOrientation(); close(stream); } catch (IOException e) { Log.e(TAG, "getExifOrientation: " + imageUri.toString(), e); } return orientation; } public static int exifToDegrees(int exifOrientation) { int rotation; switch (exifOrientation) { case ExifInterface.ORIENTATION_ROTATE_90: case ExifInterface.ORIENTATION_TRANSPOSE: rotation = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: case ExifInterface.ORIENTATION_FLIP_VERTICAL: rotation = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: case ExifInterface.ORIENTATION_TRANSVERSE: rotation = 270; break; default: rotation = 0; } return rotation; } public static int exifToTranslation(int exifOrientation) { int translation; switch (exifOrientation) { case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: case ExifInterface.ORIENTATION_FLIP_VERTICAL: case ExifInterface.ORIENTATION_TRANSPOSE: case ExifInterface.ORIENTATION_TRANSVERSE: translation = -1; break; default: translation = 1; } return translation; } /** * This method calculates maximum size of both width and height of bitmap. * It is twice the device screen diagonal for default implementation (extra quality to zoom image). * Size cannot exceed max texture size. * * @return - max bitmap size in pixels. */ @SuppressWarnings({"SuspiciousNameCombination", "deprecation"}) public static int calculateMaxBitmapSize(@NonNull Context context) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); Point size = new Point(); int width, height; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { display.getSize(size); width = size.x; height = size.y; } else { width = display.getWidth(); height = display.getHeight(); } // Twice the device screen diagonal as default int maxBitmapSize = (int) Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); // Check for max texture size via Canvas Canvas canvas = new Canvas(); final int maxCanvasSize = Math.min(canvas.getMaximumBitmapWidth(), canvas.getMaximumBitmapHeight()); if (maxCanvasSize > 0) { maxBitmapSize = Math.min(maxBitmapSize, maxCanvasSize); } // Check for max texture size via GL final int maxTextureSize = EglUtils.getMaxTextureSize(); if (maxTextureSize > 0) { maxBitmapSize = Math.min(maxBitmapSize, maxTextureSize); } Log.d(TAG, "maxBitmapSize: " + maxBitmapSize); return maxBitmapSize; } @SuppressWarnings("ConstantConditions") public static void close(@Nullable Closeable c) { if (c != null && c instanceof Closeable) { // java.lang.IncompatibleClassChangeError: interface not implemented try { c.close(); } catch (IOException e) { // silence } } } }