Merge "Fix can't create thumbnail and wrong orientation issue" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b037feb130
@@ -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));
|
||||
final Int32Ref orientation = new Int32Ref(0);
|
||||
|
||||
return ImageDecoder.decodeBitmap(ImageDecoder.createSource(() -> {
|
||||
return content.openTypedAssetFile(uri, "image/*", opts, signal);
|
||||
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} */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user