From dce34a586d7952579c9ff32b31424297ddfdaf27 Mon Sep 17 00:00:00 2001 From: M66B Date: Tue, 8 Jan 2019 09:00:15 +0000 Subject: [PATCH] Ask to resize images for screen display --- FAQ.md | 1 - .../eu/faircode/email/AdapterMessage.java | 2 +- .../java/eu/faircode/email/DaoAttachment.java | 2 +- .../eu/faircode/email/EntityAttachment.java | 6 +- .../eu/faircode/email/FragmentCompose.java | 93 +++++++++++++++++-- .../main/java/eu/faircode/email/Helper.java | 10 +- .../java/eu/faircode/email/MessageHelper.java | 2 +- app/src/main/res/values/strings.xml | 1 + 8 files changed, 98 insertions(+), 19 deletions(-) diff --git a/FAQ.md b/FAQ.md index 0b431556cd..8eae68257c 100644 --- a/FAQ.md +++ b/FAQ.md @@ -38,7 +38,6 @@ None at this moment. * Automatically go to the next message on deleting a message: since the 'next' message can either be an older or a newer message this would be confusing. You can disable auto closing in the advanced options and use the bottom navigation bar instead. * Rich text editor: besides that very few people would use this on a small mobile device, Android doesn't support a rich text editor and most rich text editor open source projects are abandoned. * Widget to read e-mail: widgets can have limited user interaction only, so a widget to read e-mail would not be very useful. Moreover, it would be not very useful to duplicate functions which are already available in the app. -* Resize images: this is not a feature directly related to email and there are plenty of apps that can do this for you. * Calendar events: opening the attached calendar file should open the related calendar app. * Executing filter rules: filter rules should be executed on the server because a battery powered device with possibly an unstable internet connection is not suitable for this. * Badge count: there is no standard Android API for this and third party solutions might stop working anytime. For example *ShortcutBadger* [has lots of problems](https://github.com/leolin310148/ShortcutBadger/issues). You can use the provided widget instead. diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 5564a7378d..bf49357ca2 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -636,7 +636,7 @@ public class AdapterMessage extends RecyclerView.Adapter images = new ArrayList<>(); for (EntityAttachment attachment : attachments) - if (attachment.type.startsWith("image") && !attachment.isInline()) + if (attachment.type.startsWith("image/") && !attachment.isInline()) images.add(attachment); adapterImage.set(images); rvImage.setVisibility(images.size() > 0 ? View.VISIBLE : View.INVISIBLE); diff --git a/app/src/main/java/eu/faircode/email/DaoAttachment.java b/app/src/main/java/eu/faircode/email/DaoAttachment.java index df4fc8577b..9cbbcb116a 100644 --- a/app/src/main/java/eu/faircode/email/DaoAttachment.java +++ b/app/src/main/java/eu/faircode/email/DaoAttachment.java @@ -66,7 +66,7 @@ public interface DaoAttachment { @Query("UPDATE attachment" + " SET size = :size, progress = NULL, available = 1" + " WHERE id = :id") - void setDownloaded(long id, Integer size); + void setDownloaded(long id, Long size); @Query("UPDATE attachment" + " SET cid = :cid" + diff --git a/app/src/main/java/eu/faircode/email/EntityAttachment.java b/app/src/main/java/eu/faircode/email/EntityAttachment.java index 529515fa65..702620c968 100644 --- a/app/src/main/java/eu/faircode/email/EntityAttachment.java +++ b/app/src/main/java/eu/faircode/email/EntityAttachment.java @@ -73,7 +73,7 @@ public class EntityAttachment { public String disposition; public String cid; // Content-ID public Integer encryption; - public Integer size; + public Long size; public Integer progress; @NonNull public Boolean available = false; @@ -117,7 +117,7 @@ public class EntityAttachment { is = this.part.getInputStream(); os = new BufferedOutputStream(new FileOutputStream(file)); - int size = 0; + long size = 0; byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE]; for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { size += len; @@ -125,7 +125,7 @@ public class EntityAttachment { // Update progress if (this.size != null) - db.attachment().setProgress(this.id, size * 100 / this.size); + db.attachment().setProgress(this.id, (int)(size * 100 / this.size)); } // Store attachment data diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 6e35421578..d2b63c78f1 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -32,6 +32,8 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.LevelListDrawable; @@ -167,6 +169,9 @@ public class FragmentCompose extends FragmentEx { private OpenPgpServiceConnection pgpService; + private static final int REDUCED_IMAGE_SIZE = 1920; + private static final int REDUCED_IMAGE_QUALITY = 90; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -910,7 +915,7 @@ public class FragmentCompose extends FragmentEx { os1 = new BufferedOutputStream(new FileOutputStream(file1)); os1.write(bytes1); - db.attachment().setDownloaded(attachment1.id, bytes1.length); + db.attachment().setDownloaded(attachment1.id, (long) bytes1.length); } finally { if (os1 != null) os1.close(); @@ -932,7 +937,7 @@ public class FragmentCompose extends FragmentEx { os2 = new BufferedOutputStream(new FileOutputStream(file2)); os2.write(bytes2); - db.attachment().setDownloaded(attachment2.id, bytes2.length); + db.attachment().setDownloaded(attachment2.id, (long) bytes2.length); } finally { if (os2 != null) os2.close(); @@ -1077,11 +1082,25 @@ public class FragmentCompose extends FragmentEx { protected EntityAttachment onExecute(Context context, Bundle args) throws IOException { Long id = args.getLong("id"); Uri uri = args.getParcelable("uri"); - return addAttachment(context, id, uri, image); + EntityAttachment attachment = addAttachment(context, id, uri, image); + + if ("image/jpeg".equals(attachment.type) || "image/png".equals(attachment.type)) { + File file = EntityAttachment.getFile(context, attachment.id); + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(file.getAbsolutePath(), options); + + int scaleTo = REDUCED_IMAGE_SIZE; + int factor = Math.min(options.outWidth / scaleTo, options.outWidth / scaleTo); + if (factor > 0) + args.putInt("factor", factor); + } + + return attachment; } @Override - protected void onExecuted(Bundle args, EntityAttachment attachment) { + protected void onExecuted(Bundle args, final EntityAttachment attachment) { if (image) { File file = EntityAttachment.getFile(getContext(), attachment.id); Drawable d = Drawable.createFromPath(file.getAbsolutePath()); @@ -1095,6 +1114,66 @@ public class FragmentCompose extends FragmentEx { String html = Html.toHtml(s); etBody.setText(Html.fromHtml(html, cidGetter, null)); } + + final int factor = args.getInt("factor", 0); + if (factor > 0) + new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner()) + .setMessage(getString(R.string.title_ask_resize, attachment.name)) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Bundle args = new Bundle(); + args.putLong("id", attachment.id); + args.putInt("factor", factor); + args.putInt("quality", REDUCED_IMAGE_QUALITY); + + new SimpleTask() { + @Override + protected Void onExecute(Context context, Bundle args) throws Throwable { + long id = args.getLong("id"); + int factor = args.getInt("factor"); + int quality = args.getInt("quality"); + + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = factor; + + File file = EntityAttachment.getFile(context, id); + Bitmap scaled = BitmapFactory.decodeFile(file.getAbsolutePath(), options); + if (scaled == null) + throw new IOException("Decode image failed"); + + Log.i("Image target size=" + scaled.getWidth() + "x" + scaled.getHeight()); + + FileOutputStream out = null; + try { + out = new FileOutputStream(file); + scaled.compress("image/jpeg".equals(attachment.type) + ? Bitmap.CompressFormat.JPEG + : Bitmap.CompressFormat.PNG, + quality, out); + } finally { + if (out != null) + out.close(); + scaled.recycle(); + } + + DB.getInstance(context).attachment().setDownloaded(id, file.length()); + + return null; + } + + @Override + protected void onException(Bundle args, Throwable ex) { + if (ex instanceof IOException) + Snackbar.make(view, Helper.formatThrowable(ex), Snackbar.LENGTH_LONG).show(); + else + Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex); + } + }.execute(FragmentCompose.this, args); + } + }) + .create() + .show(); } @Override @@ -1228,7 +1307,7 @@ public class FragmentCompose extends FragmentEx { if (image) attachment.disposition = Part.INLINE; - attachment.size = (s == null ? null : Integer.parseInt(s)); + attachment.size = (s == null ? null : Long.parseLong(s)); attachment.progress = 0; attachment.id = db.attachment().insertAttachment(attachment); @@ -1248,7 +1327,7 @@ public class FragmentCompose extends FragmentEx { is = context.getContentResolver().openInputStream(uri); os = new BufferedOutputStream(new FileOutputStream(file)); - int size = 0; + long size = 0; byte[] buffer = new byte[EntityAttachment.ATTACHMENT_BUFFER_SIZE]; for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { size += len; @@ -1256,7 +1335,7 @@ public class FragmentCompose extends FragmentEx { // Update progress if (attachment.size != null) - db.attachment().setProgress(attachment.id, size * 100 / attachment.size); + db.attachment().setProgress(attachment.id, (int) (size * 100 / attachment.size)); } if (image) { diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index 616206c1d3..1ed4631777 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -393,7 +393,7 @@ public class Helper { try { os = new BufferedOutputStream(new FileOutputStream(file)); - int size = 0; + long size = 0; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); Map settings = prefs.getAll(); @@ -424,7 +424,7 @@ public class Helper { try { os = new BufferedOutputStream(new FileOutputStream(file)); - int size = 0; + long size = 0; ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo ani = cm.getActiveNetworkInfo(); @@ -460,7 +460,7 @@ public class Helper { try { os = new BufferedOutputStream(new FileOutputStream(file)); - int size = 0; + long size = 0; long from = new Date().getTime() - 24 * 3600 * 1000L; DateFormat DF = SimpleDateFormat.getTimeInstance(); @@ -491,7 +491,7 @@ public class Helper { try { os = new BufferedOutputStream(new FileOutputStream(file)); - int size = 0; + long size = 0; DateFormat DF = SimpleDateFormat.getTimeInstance(); for (EntityOperation op : db.operation().getOperations()) @@ -536,7 +536,7 @@ public class Helper { proc = Runtime.getRuntime().exec(cmd); br = new BufferedReader(new InputStreamReader(proc.getInputStream())); - int size = 0; + long size = 0; String line; while ((line = br.readLine()) != null) diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index 81d77e6451..85846d8fcd 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -663,7 +663,7 @@ public class MessageHelper { attachment.name = filename; attachment.type = ct.getBaseType().toLowerCase(); attachment.disposition = disposition; - attachment.size = part.getSize(); + attachment.size = (long) part.getSize(); attachment.cid = (cid == null || cid.length == 0 ? null : cid[0]); attachment.encryption = (pgp ? EntityAttachment.PGP_MESSAGE : null); attachment.part = part; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 561ee0da80..465013c935 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -316,6 +316,7 @@ Send View Send after … + Reduce size of %1$s for displaying on screens? Nothing selected Bold