Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b037feb1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix can't create thumbnail and wrong orientation issue" into qt-dev

parents f3ea21a1 6da7b0ad
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -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} */
+13 −0
Original line number Diff line number Diff line
@@ -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);
    }

+52 −5
Original line number Diff line number Diff line
@@ -244,30 +244,77 @@ public class ThumbnailUtils {

        final Resizer resizer = new Resizer(size, signal);
        final String mimeType = MediaFile.getMimeTypeForFile(file.getName());
        Bitmap bitmap = null;
        ExifInterface exif = null;
        int orientation = 0;

        // get orientation
        if (MediaFile.isExifMimeType(mimeType)) {
            exif = new ExifInterface(file);
            switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    orientation = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    orientation = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    orientation = 270;
                    break;
            }
        }

        boolean isHeifFile = false;

        if (mimeType.equals("image/heif")
                || mimeType.equals("image/heif-sequence")
                || mimeType.equals("image/heic")
                || mimeType.equals("image/heic-sequence")) {
            isHeifFile = true;
            try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
                retriever.setDataSource(file.getAbsolutePath());
                return retriever.getThumbnailImageAtIndex(-1,
                bitmap = retriever.getThumbnailImageAtIndex(-1,
                        new MediaMetadataRetriever.BitmapParams(), size.getWidth(),
                        size.getWidth() * size.getHeight());
            } catch (RuntimeException e) {
                throw new IOException("Failed to create thumbnail", e);
            }
        } else if (MediaFile.isExifMimeType(mimeType)) {
            final ExifInterface exif = new ExifInterface(file);
        }

        if (bitmap == null && exif != null) {
            final byte[] raw = exif.getThumbnailBytes();
            if (raw != null) {
                return ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
                try {
                    bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
                } catch (ImageDecoder.DecodeException e) {
                    Log.w(TAG, e);
                }
            }
        }

        // Checkpoint before going deeper
        if (signal != null) signal.throwIfCanceled();

        return ImageDecoder.decodeBitmap(ImageDecoder.createSource(file), resizer);
        if (bitmap == null) {
            bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(file), resizer);
            // Use ImageDecoder to do full image decode of heif format file
            // will have right orientation. Don't rotate the bitmap again.
            if (isHeifFile) {
                return bitmap;
            }
        }

        // Transform the bitmap if the orientation of the image is not 0.
        if (orientation != 0 && bitmap != null) {
            final int width = bitmap.getWidth();
            final int height = bitmap.getHeight();

            final Matrix m = new Matrix();
            m.setRotate(orientation, width / 2, height / 2);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, false);
        }

        return bitmap;
    }

    /**