mirror of https://github.com/M66B/FairEmail.git
Use image decoder for bitmaps
This commit is contained in:
parent
610c0e625d
commit
f9e69b0919
|
@ -45,6 +45,7 @@ import android.database.MatrixCursor;
|
|||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ImageDecoder;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -2677,6 +2678,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
args.putParcelableArrayList("uris", new ArrayList<>(uris));
|
||||
args.putBoolean("image", image);
|
||||
args.putInt("resize", resize);
|
||||
args.putInt("zoom", zoom);
|
||||
args.putBoolean("privacy", privacy);
|
||||
args.putCharSequence("body", etBody.getText());
|
||||
args.putInt("start", etBody.getSelectionStart());
|
||||
|
@ -2688,6 +2690,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
List<Uri> uris = args.getParcelableArrayList("uris");
|
||||
boolean image = args.getBoolean("image");
|
||||
int resize = args.getInt("resize");
|
||||
int zoom = args.getInt("zoom");
|
||||
boolean privacy = args.getBoolean("privacy");
|
||||
CharSequence body = args.getCharSequence("body");
|
||||
int start = args.getInt("start");
|
||||
|
@ -2708,9 +2711,23 @@ public class FragmentCompose extends FragmentBase {
|
|||
File file = attachment.getFile(context);
|
||||
Uri cid = Uri.parse("cid:" + BuildConfig.APPLICATION_ID + "." + attachment.id);
|
||||
|
||||
Drawable d = Drawable.createFromPath(file.getAbsolutePath());
|
||||
if (d == null)
|
||||
throw new IllegalArgumentException(context.getString(R.string.title_no_image));
|
||||
Drawable d;
|
||||
try {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
|
||||
ImageDecoder.Source source = ImageDecoder.createSource(file.getAbsoluteFile());
|
||||
d = ImageDecoder.decodeDrawable(source);
|
||||
} else
|
||||
d = Drawable.createFromPath(file.getAbsolutePath());
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
d = Drawable.createFromPath(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (d == null) {
|
||||
int px = Helper.dp2pixels(context, (zoom + 1) * 24);
|
||||
d = context.getDrawable(R.drawable.twotone_broken_image_24);
|
||||
d.setBounds(0, 0, px, px);
|
||||
}
|
||||
|
||||
s.insert(start, "\n\uFFFC\n"); // Object replacement character
|
||||
ImageSpan is = new ImageSpan(context, cid);
|
||||
|
|
|
@ -760,9 +760,12 @@ class ImageHelper {
|
|||
static Bitmap getScaledBitmap(InputStream is, String source, String mimeType, int scaleToPixels) throws IOException {
|
||||
if (TextUtils.isEmpty(mimeType))
|
||||
mimeType = Helper.guessMimeType(source);
|
||||
|
||||
if ("image/svg+xml".equals(mimeType))
|
||||
return ImageHelper.renderSvg(is, Color.WHITE, scaleToPixels);
|
||||
|
||||
// ImageDecoder cannot decode streams
|
||||
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
|
||||
Log.i("Probe " + source);
|
||||
|
@ -805,36 +808,63 @@ class ImageHelper {
|
|||
private static Bitmap _decodeImage(File file, String mimeType, int scaleToPixels) throws IOException {
|
||||
if (mimeType == null)
|
||||
mimeType = Helper.guessMimeType(file.getName());
|
||||
|
||||
if ("image/svg+xml".equals(mimeType))
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
return ImageHelper.renderSvg(fis, Color.WHITE, scaleToPixels);
|
||||
}
|
||||
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
Bitmap bm = null;
|
||||
|
||||
int factor = 1;
|
||||
while (options.outWidth / factor > scaleToPixels)
|
||||
factor *= 2;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
|
||||
try {
|
||||
ImageDecoder.Source isource = ImageDecoder.createSource(file);
|
||||
bm = ImageDecoder.decodeBitmap(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;
|
||||
|
||||
Matrix rotation = getImageRotation(file);
|
||||
if (factor > 1 || rotation != null) {
|
||||
Log.i("Decode image factor=" + factor);
|
||||
options.inJustDecodeBounds = false;
|
||||
options.inSampleSize = factor;
|
||||
Bitmap scaled = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
|
||||
if (scaled != null && rotation != null) {
|
||||
Bitmap rotated = Bitmap.createBitmap(scaled, 0, 0, scaled.getWidth(), scaled.getHeight(), rotation, true);
|
||||
scaled.recycle();
|
||||
scaled = rotated;
|
||||
Log.i("Decode image (decoder) factor=" + factor);
|
||||
decoder.setTargetSampleSize(factor);
|
||||
}
|
||||
});
|
||||
} catch (Throwable ex) {
|
||||
Log.i(ex);
|
||||
}
|
||||
|
||||
return scaled;
|
||||
if (bm == null) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
|
||||
int factor = 1;
|
||||
while (options.outWidth / factor > scaleToPixels)
|
||||
factor *= 2;
|
||||
|
||||
if (factor > 1) {
|
||||
Log.i("Decode image (factory) factor=" + factor);
|
||||
options.inJustDecodeBounds = false;
|
||||
options.inSampleSize = factor;
|
||||
bm = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
} else
|
||||
bm = BitmapFactory.decodeFile(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
return BitmapFactory.decodeFile(file.getAbsolutePath());
|
||||
if (bm != null) {
|
||||
Matrix rotation = getImageRotation(file);
|
||||
if (rotation != null) {
|
||||
Bitmap rotated = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), rotation, true);
|
||||
bm.recycle();
|
||||
bm = rotated;
|
||||
}
|
||||
}
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
static Matrix getImageRotation(File file) {
|
||||
|
|
|
@ -1055,7 +1055,6 @@
|
|||
<string name="title_no_connection">Connecting to one or more accounts …</string>
|
||||
<string name="title_no_folder">Folder does not exist</string>
|
||||
<string name="title_no_format">The originally received message will be included</string>
|
||||
<string name="title_no_image">Image could not be decoded</string>
|
||||
<string name="title_no_search">Search on server is not available for this account</string>
|
||||
<string name="title_too_large">Message too large to completely reformat</string>
|
||||
<string name="title_truncated">Message too large to display completely</string>
|
||||
|
|
Loading…
Reference in New Issue