use JPEG as file format for avatar and compress to <9400 chars

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/Config.java                           |   3 
src/main/java/eu/siacs/conversations/persistance/FileBackend.java          |  39 
src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java | 116 
src/main/res/layout/activity_publish_profile_picture.xml                   |   8 
4 files changed, 69 insertions(+), 97 deletions(-)

Detailed changes

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;

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();
 			}

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);

src/main/res/layout/activity_publish_profile_picture.xml 🔗

@@ -84,14 +84,6 @@
         android:orientation="vertical"
         android:paddingLeft="8dp"
         android:paddingRight="8dp" >
-
-        <TextView
-            android:id="@+id/account"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textColor="?attr/color_text_primary"
-            android:textSize="?attr/TextSizeHeadline" />
-
         <TextView
             android:id="@+id/hint_or_warning"
             android:layout_width="wrap_content"