diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/content/ContentResolver.java | 29 | ||||
| -rw-r--r-- | core/java/android/provider/DocumentsContract.java | 13 |
2 files changed, 39 insertions, 3 deletions
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 5f34f1b2bc0d..804677648d09 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -16,6 +16,8 @@ package android.content; +import static android.provider.DocumentsContract.EXTRA_ORIENTATION; + import android.accounts.Account; import android.annotation.IntDef; import android.annotation.NonNull; @@ -40,6 +42,7 @@ import android.graphics.Bitmap; import android.graphics.ImageDecoder; import android.graphics.ImageDecoder.ImageInfo; import android.graphics.ImageDecoder.Source; +import android.graphics.Matrix; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; @@ -56,6 +59,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.storage.StorageManager; +import android.system.Int32Ref; import android.text.TextUtils; import android.util.EventLog; import android.util.Log; @@ -3563,9 +3567,14 @@ public abstract class ContentResolver implements ContentInterface { // Convert to Point, since that's what the API is defined as final Bundle opts = new Bundle(); opts.putParcelable(EXTRA_SIZE, Point.convert(size)); - - return ImageDecoder.decodeBitmap(ImageDecoder.createSource(() -> { - return content.openTypedAssetFile(uri, "image/*", opts, signal); + final Int32Ref orientation = new Int32Ref(0); + + Bitmap bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(() -> { + final AssetFileDescriptor afd = content.openTypedAssetFile(uri, "image/*", opts, + signal); + final Bundle extras = afd.getExtras(); + orientation.value = (extras != null) ? extras.getInt(EXTRA_ORIENTATION, 0) : 0; + return afd; }), (ImageDecoder decoder, ImageInfo info, Source source) -> { decoder.setAllocator(allocator); @@ -3581,6 +3590,20 @@ public abstract class ContentResolver implements ContentInterface { decoder.setTargetSampleSize(sample); } }); + + // Transform the bitmap if requested. We use a side-channel to + // communicate the orientation, since EXIF thumbnails don't contain + // the rotation flags of the original image. + if (orientation.value != 0) { + final int width = bitmap.getWidth(); + final int height = bitmap.getHeight(); + + final Matrix m = new Matrix(); + m.setRotate(orientation.value, width / 2, height / 2); + bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, false); + } + + return bitmap; } /** {@hide} */ diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 4632b7553ca0..4ac485099da8 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -36,6 +36,7 @@ import android.graphics.Bitmap; import android.graphics.ImageDecoder; import android.graphics.Point; import android.media.ExifInterface; +import android.media.MediaFile; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -1698,6 +1699,18 @@ public final class DocumentsContract { } catch (IOException e) { } + // Use ImageDecoder to do full image decode of heif format file + // will have right orientation. So, we don't need to add orientation + // information into extras. + final String mimeType = MediaFile.getMimeTypeForFile(file.getName()); + if (mimeType.equals("image/heif") + || mimeType.equals("image/heif-sequence") + || mimeType.equals("image/heic") + || mimeType.equals("image/heic-sequence")) { + return new AssetFileDescriptor(pfd, 0 /* startOffset */, + AssetFileDescriptor.UNKNOWN_LENGTH, null /* extras */); + } + return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH, extras); } |
