From d836ac2049074a0dd2fc71953f804c7021dabd63 Mon Sep 17 00:00:00 2001 From: judds Date: Fri, 25 Aug 2017 11:09:42 -0700 Subject: [PATCH] Avoid hardware bitmaps when rotation is required. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=166499393 --- .../load/resource/bitmap/Downsampler.java | 21 ++++++++++++--- .../resource/bitmap/HardwareConfigState.java | 6 +++-- .../resource/bitmap/TransformationUtils.java | 26 ++++++++++++++++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java index eab67c1e6..0ecfa83ac 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/Downsampler.java @@ -224,13 +224,21 @@ public final class Downsampler { int orientation = ImageHeaderParserUtils.getOrientation(parsers, is, byteArrayPool); int degreesToRotate = TransformationUtils.getExifOrientationDegrees(orientation); + boolean isExifOrientationRequired = TransformationUtils.isExifOrientationRequired(orientation); int targetWidth = requestedWidth == Target.SIZE_ORIGINAL ? sourceWidth : requestedWidth; int targetHeight = requestedHeight == Target.SIZE_ORIGINAL ? sourceHeight : requestedHeight; calculateScaling(downsampleStrategy, degreesToRotate, sourceWidth, sourceHeight, targetWidth, targetHeight, options); - calculateConfig(is, decodeFormat, isHardwareConfigAllowed, options, targetWidth, targetHeight); + calculateConfig( + is, + decodeFormat, + isHardwareConfigAllowed, + isExifOrientationRequired, + options, + targetWidth, + targetHeight); boolean isKitKatOrGreater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // Prior to KitKat, the inBitmap size must exactly match the size of the bitmap we're decoding. @@ -289,7 +297,8 @@ public final class Downsampler { } // Visible for testing. - static void calculateScaling(DownsampleStrategy downsampleStrategy, int degreesToRotate, + static void calculateScaling(DownsampleStrategy downsampleStrategy, + int degreesToRotate, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight, BitmapFactory.Options options) { // We can't downsample source content if we can't determine its dimensions. @@ -394,13 +403,19 @@ public final class Downsampler { InputStream is, DecodeFormat format, boolean isHardwareConfigAllowed, + boolean isExifOrientationRequired, BitmapFactory.Options optionsWithScaling, int targetWidth, int targetHeight) throws IOException { if (hardwareConfigState.setHardwareConfigIfAllowed( - targetWidth, targetHeight, optionsWithScaling, format, isHardwareConfigAllowed)) { + targetWidth, + targetHeight, + optionsWithScaling, + format, + isHardwareConfigAllowed, + isExifOrientationRequired)) { return; } diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/HardwareConfigState.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/HardwareConfigState.java index d068011e8..2d7c44f40 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/HardwareConfigState.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/HardwareConfigState.java @@ -75,10 +75,12 @@ final class HardwareConfigState { int targetHeight, BitmapFactory.Options optionsWithScaling, DecodeFormat decodeFormat, - boolean isHardwareConfigAllowed) { + boolean isHardwareConfigAllowed, + boolean isExifOrientationRequired) { if (!isHardwareConfigAllowed || Build.VERSION.SDK_INT < Build.VERSION_CODES.O - || decodeFormat == DecodeFormat.PREFER_ARGB_8888_DISALLOW_HARDWARE) { + || decodeFormat == DecodeFormat.PREFER_ARGB_8888_DISALLOW_HARDWARE + || isExifOrientationRequired) { return false; } diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java index e7abbb8ab..2f6d60698 100644 --- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java +++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java @@ -264,12 +264,13 @@ public final class TransformationUtils { */ public static Bitmap rotateImageExif(@NonNull BitmapPool pool, @NonNull Bitmap inBitmap, int exifOrientation) { - final Matrix matrix = new Matrix(); - initializeMatrixForRotation(exifOrientation, matrix); - if (matrix.isIdentity()) { + if (!isExifOrientationRequired(exifOrientation)) { return inBitmap; } + final Matrix matrix = new Matrix(); + initializeMatrixForRotation(exifOrientation, matrix); + // From Bitmap.createBitmap. final RectF newRect = new RectF(0, 0, inBitmap.getWidth(), inBitmap.getHeight()); matrix.mapRect(newRect); @@ -286,6 +287,25 @@ public final class TransformationUtils { return result; } + /** + * Returns {@code true} if the given exif orientation indicates that a transformation is necessary + * and {@code false} otherwise. + */ + public static boolean isExifOrientationRequired(int exifOrientation) { + switch (exifOrientation) { + case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: + case ExifInterface.ORIENTATION_ROTATE_180: + case ExifInterface.ORIENTATION_FLIP_VERTICAL: + case ExifInterface.ORIENTATION_TRANSPOSE: + case ExifInterface.ORIENTATION_ROTATE_90: + case ExifInterface.ORIENTATION_TRANSVERSE: + case ExifInterface.ORIENTATION_ROTATE_270: + return true; + default: + return false; + } + } + /** * Crop the image to a circle and resize to the specified width/height. The circle crop will * have the same width and height equal to the min-edge of the result image. -- GitLab