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

This commit is contained in:
Daniel Gultsch 2017-12-15 20:49:48 +01:00
parent 0be41e0aab
commit bb6d5463fe
4 changed files with 69 additions and 97 deletions

View file

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

View file

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

View file

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

View file

@ -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"