Added support for downloaded animated images (GIFs)

This commit is contained in:
M66B 2020-09-03 15:13:06 +02:00
parent 69fdfdfe7d
commit 3de3e6215b
1 changed files with 48 additions and 30 deletions

View File

@ -34,6 +34,7 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
@ -51,6 +52,7 @@ import android.view.ViewParent;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.graphics.ColorUtils;
import androidx.exifinterface.media.ExifInterface;
import androidx.preference.PreferenceManager;
@ -264,37 +266,17 @@ class ImageHelper {
return d;
} else {
int scaleToPixels = res.getDisplayMetrics().widthPixels;
if ("image/gif".equals(attachment.type) &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ImageDecoder.Source isource = ImageDecoder.createSource(attachment.getFile(context));
Drawable gif;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
gif = ImageDecoder.decodeDrawable(isource, new ImageDecoder.OnHeaderDecodedListener() {
@Override
public void onHeaderDecoded(
@NonNull ImageDecoder decoder,
@NonNull ImageDecoder.ImageInfo info,
@NonNull ImageDecoder.Source source) {
int factor = 1;
while (info.getSize().getWidth() / factor > scaleToPixels)
factor *= 2;
decoder.setTargetSampleSize(factor);
}
});
Drawable d = getScaledDrawable(attachment.getFile(context), scaleToPixels);
if (view != null)
fitDrawable(d, a, view);
return d;
} catch (IOException ex) {
Log.w(ex);
gif = null;
}
if (gif == null) {
Log.i("GIF not decodable CID=" + cid);
Drawable d = res.getDrawable(R.drawable.baseline_broken_image_24, theme);
d.setBounds(0, 0, px, px);
return d;
} else {
if (view != null)
fitDrawable(gif, a, view);
return gif;
}
} else {
Bitmap bm = decodeImage(attachment.getFile(context), scaleToPixels);
@ -476,6 +458,11 @@ class ImageHelper {
lld.setBounds(0, 0, bounds.width(), bounds.height());
lld.setLevel(0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (d instanceof AnimatedImageDrawable)
((AnimatedImageDrawable) d).start();
}
view.requestLayout();
}
});
@ -545,22 +532,25 @@ class ImageHelper {
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
private static Drawable getCachedImage(Context context, long id, String source) {
private static Drawable getCachedImage(Context context, long id, String source) throws IOException {
if (id < 0)
return null;
File file = getCacheFile(context, id, source, ".png");
File file = getCacheFile(context, id, source,
Build.VERSION.SDK_INT < Build.VERSION_CODES.P ? ".png" : ".blob");
if (file.exists()) {
Log.i("Using cached " + file);
file.setLastModified(new Date().getTime());
DisplayMetrics dm = context.getResources().getDisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
return getScaledDrawable(file, dm.widthPixels);
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
if (bm != null) {
Drawable d = new BitmapDrawable(context.getResources(), bm);
DisplayMetrics dm = context.getResources().getDisplayMetrics();
d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density));
return d;
}
}
@ -623,6 +613,14 @@ class ImageHelper {
break;
}
if (id > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
File file = getCacheFile(context, id, source, ".blob");
try (FileOutputStream fos = new FileOutputStream(file)) {
Helper.copy(urlConnection.getInputStream(), fos);
}
return getScaledDrawable(file, dm.widthPixels);
}
bm = getScaledBitmap(urlConnection.getInputStream(), source, dm.widthPixels);
} finally {
if (urlConnection != null)
@ -646,6 +644,26 @@ class ImageHelper {
return d;
}
@RequiresApi(api = Build.VERSION_CODES.P)
static Drawable getScaledDrawable(File file, int scaleToPixels) throws IOException {
ImageDecoder.Source isource = ImageDecoder.createSource(file);
Drawable d = ImageDecoder.decodeDrawable(isource, new ImageDecoder.OnHeaderDecodedListener() {
@Override
public void onHeaderDecoded(
@NonNull ImageDecoder decoder,
@NonNull ImageDecoder.ImageInfo info,
@NonNull ImageDecoder.Source source) {
int factor = 1;
while (info.getSize().getWidth() / factor > scaleToPixels)
factor *= 2;
decoder.setTargetSampleSize(factor);
}
});
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
return d;
}
static Bitmap getScaledBitmap(InputStream is, String source, int scaleToPixels) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);