mirror of
https://github.com/M66B/FairEmail.git
synced 2024-12-27 02:07:12 +00:00
Added support for downloaded animated images (GIFs)
This commit is contained in:
parent
69fdfdfe7d
commit
3de3e6215b
1 changed files with 48 additions and 30 deletions
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue