From bb6d5463fe5bde474237a1bad2c51f6bf032c4f0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 Dec 2017 20:49:48 +0100 Subject: [PATCH] use JPEG as file format for avatar and compress to <9400 chars --- .../java/eu/siacs/conversations/Config.java | 3 +- .../persistance/FileBackend.java | 39 +++--- .../ui/PublishProfilePictureActivity.java | 116 +++++++----------- .../activity_publish_profile_picture.xml | 8 -- 4 files changed, 69 insertions(+), 97 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 0011f1386..09f9fd4d2 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -61,7 +61,8 @@ public final class Config { public static final int MINI_GRACE_PERIOD = 750; public static final int AVATAR_SIZE = 192; - public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP; + public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.JPEG; + public static final int AVATAR_CHAR_LIMIT = 9400; public static final int IMAGE_SIZE = 1920; public static final Bitmap.CompressFormat IMAGE_FORMAT = Bitmap.CompressFormat.JPEG; diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 74560c71f..4d73dbed4 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -535,29 +535,36 @@ public class FileBackend { } public Avatar getPepAvatar(Uri image, int size, Bitmap.CompressFormat format) { + Bitmap bm = cropCenterSquare(image, size); + if (bm == null) { + return null; + } + return getPepAvatar(bm,format,100); + } + + private Avatar getPepAvatar(Bitmap bitmap, Bitmap.CompressFormat format, int quality) { try { - Avatar avatar = new Avatar(); - Bitmap bm = cropCenterSquare(image, size); - if (bm == null) { - return null; - } ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream(); - Base64OutputStream mBase64OutputStream = new Base64OutputStream( - mByteArrayOutputStream, Base64.DEFAULT); + Base64OutputStream mBase64OutputStream = new Base64OutputStream(mByteArrayOutputStream, Base64.DEFAULT); MessageDigest digest = MessageDigest.getInstance("SHA-1"); - DigestOutputStream mDigestOutputStream = new DigestOutputStream( - mBase64OutputStream, digest); - if (!bm.compress(format, 75, mDigestOutputStream)) { + DigestOutputStream mDigestOutputStream = new DigestOutputStream(mBase64OutputStream, digest); + if (!bitmap.compress(format, quality, mDigestOutputStream)) { return null; } mDigestOutputStream.flush(); mDigestOutputStream.close(); + long chars = mByteArrayOutputStream.size(); + if (quality >= 50 && chars >= Config.AVATAR_CHAR_LIMIT) { + int q = quality - 2; + Log.d(Config.LOGTAG,"avatar char length was "+chars+" reducing quality to "+q); + return getPepAvatar(bitmap,format,q); + } + Log.d(Config.LOGTAG,"settled on char length "+chars+" with quality="+quality); + final Avatar avatar = new Avatar(); avatar.sha1sum = CryptoHelper.bytesToHex(digest.digest()); avatar.image = new String(mByteArrayOutputStream.toByteArray()); return avatar; - } catch (NoSuchAlgorithmException e) { - return null; - } catch (IOException e) { + } catch (Exception e) { return null; } } @@ -709,7 +716,11 @@ public class FileBackend { RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight); Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(dest); - canvas.drawBitmap(source, null, targetRect, null); + Paint p = new Paint(); + p.setAntiAlias(true); + p.setFilterBitmap(true); + p.setDither(true); + canvas.drawBitmap(source, null, targetRect, p); if (source.isRecycled()) { source.recycle(); } diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index fe18b5478..48ec42242 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -6,10 +6,10 @@ import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.NonNull; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.widget.Button; import android.widget.ImageView; @@ -20,7 +20,6 @@ import com.soundcloud.android.crop.Crop; import java.io.File; -import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.persistance.FileBackend; @@ -33,7 +32,6 @@ public class PublishProfilePictureActivity extends XmppActivity { private static final int REQUEST_CHOOSE_FILE_AND_CROP = 0xac23; private static final int REQUEST_CHOOSE_FILE = 0xac24; private ImageView avatar; - private TextView accountTextView; private TextView hintOrWarning; private TextView secondaryHint; private Button cancelButton; @@ -56,35 +54,27 @@ public class PublishProfilePictureActivity extends XmppActivity { @Override public void success(Avatar object) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - if (mInitialAccountSetup) { - Intent intent = new Intent(getApplicationContext(), - StartConversationActivity.class); - intent.putExtra("init", true); - startActivity(intent); - } - Toast.makeText(PublishProfilePictureActivity.this, - R.string.avatar_has_been_published, - Toast.LENGTH_SHORT).show(); - finish(); + runOnUiThread(() -> { + if (mInitialAccountSetup) { + Intent intent = new Intent(getApplicationContext(), + StartConversationActivity.class); + intent.putExtra("init", true); + startActivity(intent); } + Toast.makeText(PublishProfilePictureActivity.this, + R.string.avatar_has_been_published, + Toast.LENGTH_SHORT).show(); + finish(); }); } @Override public void error(final int errorCode, Avatar object) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - hintOrWarning.setText(errorCode); - hintOrWarning.setTextColor(getWarningTextColor()); - publishButton.setText(R.string.publish); - enablePublishButton(); - } + runOnUiThread(() -> { + hintOrWarning.setText(errorCode); + hintOrWarning.setTextColor(getWarningTextColor()); + publishButton.setText(R.string.publish); + enablePublishButton(); }); } @@ -98,48 +88,35 @@ public class PublishProfilePictureActivity extends XmppActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_publish_profile_picture); - this.avatar = (ImageView) findViewById(R.id.account_image); - this.cancelButton = (Button) findViewById(R.id.cancel_button); - this.publishButton = (Button) findViewById(R.id.publish_button); - this.accountTextView = (TextView) findViewById(R.id.account); - this.hintOrWarning = (TextView) findViewById(R.id.hint_or_warning); - this.secondaryHint = (TextView) findViewById(R.id.secondary_hint); - this.publishButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (avatarUri != null) { - publishButton.setText(R.string.publishing); - disablePublishButton(); - xmppConnectionService.publishAvatar(account, avatarUri, - avatarPublication); - } + this.avatar = findViewById(R.id.account_image); + this.cancelButton = findViewById(R.id.cancel_button); + this.publishButton = findViewById(R.id.publish_button); + this.hintOrWarning = findViewById(R.id.hint_or_warning); + this.secondaryHint = findViewById(R.id.secondary_hint); + this.publishButton.setOnClickListener(v -> { + if (avatarUri != null) { + publishButton.setText(R.string.publishing); + disablePublishButton(); + xmppConnectionService.publishAvatar(account, avatarUri, + avatarPublication); } }); - this.cancelButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (mInitialAccountSetup) { - Intent intent = new Intent(getApplicationContext(), - StartConversationActivity.class); - if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) { - intent.putExtra("init", true); - } - startActivity(intent); + this.cancelButton.setOnClickListener(v -> { + if (mInitialAccountSetup) { + Intent intent = new Intent(getApplicationContext(), + StartConversationActivity.class); + if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) { + intent.putExtra("init", true); } - finish(); + startActivity(intent); } + finish(); }); - this.avatar.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (hasStoragePermission(REQUEST_CHOOSE_FILE)) { - chooseAvatar(false); - } - + this.avatar.setOnClickListener(v -> { + if (hasStoragePermission(REQUEST_CHOOSE_FILE)) { + chooseAvatar(false); } + }); this.defaultUri = PhoneHelper.getProfilePictureUri(getApplicationContext()); } @@ -153,7 +130,7 @@ public class PublishProfilePictureActivity extends XmppActivity { } @Override - public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { if (grantResults.length > 0) if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (requestCode == REQUEST_CHOOSE_FILE_AND_CROP) { @@ -248,8 +225,7 @@ public class PublishProfilePictureActivity extends XmppActivity { this.secondaryHint.setVisibility(View.INVISIBLE); } if (!support) { - this.hintOrWarning - .setTextColor(getWarningTextColor()); + this.hintOrWarning.setTextColor(getWarningTextColor()); if (account.getStatus() == Account.State.ONLINE) { this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support); } else { @@ -264,13 +240,6 @@ public class PublishProfilePictureActivity extends XmppActivity { } else { loadImageIntoPreview(avatarUri); } - String account; - if (Config.DOMAIN_LOCK != null) { - account = this.account.getJid().getLocalpart(); - } else { - account = this.account.getJid().toBareJid().toString(); - } - this.accountTextView.setText(account); } } @@ -296,8 +265,7 @@ public class PublishProfilePictureActivity extends XmppActivity { if (bm == null) { disablePublishButton(); this.hintOrWarning.setTextColor(getWarningTextColor()); - this.hintOrWarning - .setText(R.string.error_publish_avatar_converting); + this.hintOrWarning.setText(R.string.error_publish_avatar_converting); return; } this.avatar.setImageBitmap(bm); diff --git a/src/main/res/layout/activity_publish_profile_picture.xml b/src/main/res/layout/activity_publish_profile_picture.xml index de0e1de36..46a17b4a5 100644 --- a/src/main/res/layout/activity_publish_profile_picture.xml +++ b/src/main/res/layout/activity_publish_profile_picture.xml @@ -84,14 +84,6 @@ android:orientation="vertical" android:paddingLeft="8dp" android:paddingRight="8dp" > - - -