Use ImageDecoder in ImageView.getDrawableFromUri
Bug: 63909536 Test: Existing CTS tests ImageDecoder will bypass the InputStream if possible, allowing it to be more efficient. In addition, it handles density scaling differently; instead of using more RAM to scale the image up, it results in scaling at draw time. Change-Id: Ied7c0865a736f9ef0de367299264e18ccc3e0b92
This commit is contained in:
@@ -23,10 +23,12 @@ import android.annotation.TestApi;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.ImageDecoder;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
@@ -53,7 +55,6 @@ import android.widget.RemoteViews.RemoteView;
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Displays image resources, for example {@link android.graphics.Bitmap}
|
||||
@@ -946,21 +947,15 @@ public class ImageView extends View {
|
||||
}
|
||||
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
|
||||
|| ContentResolver.SCHEME_FILE.equals(scheme)) {
|
||||
InputStream stream = null;
|
||||
try {
|
||||
stream = mContext.getContentResolver().openInputStream(uri);
|
||||
return Drawable.createFromResourceStream(sCompatUseCorrectStreamDensity
|
||||
? getResources() : null, null, stream, null);
|
||||
} catch (Exception e) {
|
||||
Resources res = sCompatUseCorrectStreamDensity ? getResources() : null;
|
||||
ImageDecoder.Source src = ImageDecoder.createSource(mContext.getContentResolver(),
|
||||
uri, res);
|
||||
return ImageDecoder.decodeDrawable(src, (decoder, info, s) -> {
|
||||
decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Log.w(LOG_TAG, "Unable to open content: " + uri, e);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
Log.w(LOG_TAG, "Unable to close content: " + uri, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Drawable.createFromPath(uri.toString());
|
||||
|
||||
@@ -74,7 +74,7 @@ public final class ImageDecoder implements AutoCloseable {
|
||||
int getDensity() { return Bitmap.DENSITY_NONE; }
|
||||
|
||||
/* @hide */
|
||||
int computeDstDensity() {
|
||||
final int computeDstDensity() {
|
||||
Resources res = getResources();
|
||||
if (res == null) {
|
||||
return Bitmap.getDefaultDensity();
|
||||
@@ -122,13 +122,19 @@ public final class ImageDecoder implements AutoCloseable {
|
||||
}
|
||||
|
||||
private static class ContentResolverSource extends Source {
|
||||
ContentResolverSource(@NonNull ContentResolver resolver, @NonNull Uri uri) {
|
||||
ContentResolverSource(@NonNull ContentResolver resolver, @NonNull Uri uri,
|
||||
@Nullable Resources res) {
|
||||
mResolver = resolver;
|
||||
mUri = uri;
|
||||
mResources = res;
|
||||
}
|
||||
|
||||
private final ContentResolver mResolver;
|
||||
private final Uri mUri;
|
||||
private final Resources mResources;
|
||||
|
||||
@Nullable
|
||||
Resources getResources() { return mResources; }
|
||||
|
||||
@Override
|
||||
public ImageDecoder createImageDecoder() throws IOException {
|
||||
@@ -511,7 +517,18 @@ public final class ImageDecoder implements AutoCloseable {
|
||||
@NonNull
|
||||
public static Source createSource(@NonNull ContentResolver cr,
|
||||
@NonNull Uri uri) {
|
||||
return new ContentResolverSource(cr, uri);
|
||||
return new ContentResolverSource(cr, uri, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide Resources for density scaling.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public static Source createSource(@NonNull ContentResolver cr,
|
||||
@NonNull Uri uri, @Nullable Resources res) {
|
||||
return new ContentResolverSource(cr, uri, res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user