use JPEG as file format for avatar and compress to <9400 chars
This commit is contained in:
parent
0be41e0aab
commit
bb6d5463fe
|
@ -61,7 +61,8 @@ public final class Config {
|
||||||
public static final int MINI_GRACE_PERIOD = 750;
|
public static final int MINI_GRACE_PERIOD = 750;
|
||||||
|
|
||||||
public static final int AVATAR_SIZE = 192;
|
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 int IMAGE_SIZE = 1920;
|
||||||
public static final Bitmap.CompressFormat IMAGE_FORMAT = Bitmap.CompressFormat.JPEG;
|
public static final Bitmap.CompressFormat IMAGE_FORMAT = Bitmap.CompressFormat.JPEG;
|
||||||
|
|
|
@ -535,29 +535,36 @@ public class FileBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Avatar getPepAvatar(Uri image, int size, Bitmap.CompressFormat format) {
|
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 {
|
try {
|
||||||
Avatar avatar = new Avatar();
|
|
||||||
Bitmap bm = cropCenterSquare(image, size);
|
|
||||||
if (bm == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
Base64OutputStream mBase64OutputStream = new Base64OutputStream(
|
Base64OutputStream mBase64OutputStream = new Base64OutputStream(mByteArrayOutputStream, Base64.DEFAULT);
|
||||||
mByteArrayOutputStream, Base64.DEFAULT);
|
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||||
DigestOutputStream mDigestOutputStream = new DigestOutputStream(
|
DigestOutputStream mDigestOutputStream = new DigestOutputStream(mBase64OutputStream, digest);
|
||||||
mBase64OutputStream, digest);
|
if (!bitmap.compress(format, quality, mDigestOutputStream)) {
|
||||||
if (!bm.compress(format, 75, mDigestOutputStream)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
mDigestOutputStream.flush();
|
mDigestOutputStream.flush();
|
||||||
mDigestOutputStream.close();
|
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.sha1sum = CryptoHelper.bytesToHex(digest.digest());
|
||||||
avatar.image = new String(mByteArrayOutputStream.toByteArray());
|
avatar.image = new String(mByteArrayOutputStream.toByteArray());
|
||||||
return avatar;
|
return avatar;
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (Exception e) {
|
||||||
return null;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -709,7 +716,11 @@ public class FileBackend {
|
||||||
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
|
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
|
||||||
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
|
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
|
||||||
Canvas canvas = new Canvas(dest);
|
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()) {
|
if (source.isRecycled()) {
|
||||||
source.recycle();
|
source.recycle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.View.OnLongClickListener;
|
import android.view.View.OnLongClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
@ -20,7 +20,6 @@ import com.soundcloud.android.crop.Crop;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.persistance.FileBackend;
|
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_AND_CROP = 0xac23;
|
||||||
private static final int REQUEST_CHOOSE_FILE = 0xac24;
|
private static final int REQUEST_CHOOSE_FILE = 0xac24;
|
||||||
private ImageView avatar;
|
private ImageView avatar;
|
||||||
private TextView accountTextView;
|
|
||||||
private TextView hintOrWarning;
|
private TextView hintOrWarning;
|
||||||
private TextView secondaryHint;
|
private TextView secondaryHint;
|
||||||
private Button cancelButton;
|
private Button cancelButton;
|
||||||
|
@ -56,35 +54,27 @@ public class PublishProfilePictureActivity extends XmppActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void success(Avatar object) {
|
public void success(Avatar object) {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(() -> {
|
||||||
|
if (mInitialAccountSetup) {
|
||||||
@Override
|
Intent intent = new Intent(getApplicationContext(),
|
||||||
public void run() {
|
StartConversationActivity.class);
|
||||||
if (mInitialAccountSetup) {
|
intent.putExtra("init", true);
|
||||||
Intent intent = new Intent(getApplicationContext(),
|
startActivity(intent);
|
||||||
StartConversationActivity.class);
|
|
||||||
intent.putExtra("init", true);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
Toast.makeText(PublishProfilePictureActivity.this,
|
|
||||||
R.string.avatar_has_been_published,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
finish();
|
|
||||||
}
|
}
|
||||||
|
Toast.makeText(PublishProfilePictureActivity.this,
|
||||||
|
R.string.avatar_has_been_published,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(final int errorCode, Avatar object) {
|
public void error(final int errorCode, Avatar object) {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(() -> {
|
||||||
|
hintOrWarning.setText(errorCode);
|
||||||
@Override
|
hintOrWarning.setTextColor(getWarningTextColor());
|
||||||
public void run() {
|
publishButton.setText(R.string.publish);
|
||||||
hintOrWarning.setText(errorCode);
|
enablePublishButton();
|
||||||
hintOrWarning.setTextColor(getWarningTextColor());
|
|
||||||
publishButton.setText(R.string.publish);
|
|
||||||
enablePublishButton();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -98,48 +88,35 @@ public class PublishProfilePictureActivity extends XmppActivity {
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_publish_profile_picture);
|
setContentView(R.layout.activity_publish_profile_picture);
|
||||||
this.avatar = (ImageView) findViewById(R.id.account_image);
|
this.avatar = findViewById(R.id.account_image);
|
||||||
this.cancelButton = (Button) findViewById(R.id.cancel_button);
|
this.cancelButton = findViewById(R.id.cancel_button);
|
||||||
this.publishButton = (Button) findViewById(R.id.publish_button);
|
this.publishButton = findViewById(R.id.publish_button);
|
||||||
this.accountTextView = (TextView) findViewById(R.id.account);
|
this.hintOrWarning = findViewById(R.id.hint_or_warning);
|
||||||
this.hintOrWarning = (TextView) findViewById(R.id.hint_or_warning);
|
this.secondaryHint = findViewById(R.id.secondary_hint);
|
||||||
this.secondaryHint = (TextView) findViewById(R.id.secondary_hint);
|
this.publishButton.setOnClickListener(v -> {
|
||||||
this.publishButton.setOnClickListener(new OnClickListener() {
|
if (avatarUri != null) {
|
||||||
|
publishButton.setText(R.string.publishing);
|
||||||
@Override
|
disablePublishButton();
|
||||||
public void onClick(View v) {
|
xmppConnectionService.publishAvatar(account, avatarUri,
|
||||||
if (avatarUri != null) {
|
avatarPublication);
|
||||||
publishButton.setText(R.string.publishing);
|
|
||||||
disablePublishButton();
|
|
||||||
xmppConnectionService.publishAvatar(account, avatarUri,
|
|
||||||
avatarPublication);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.cancelButton.setOnClickListener(new OnClickListener() {
|
this.cancelButton.setOnClickListener(v -> {
|
||||||
|
if (mInitialAccountSetup) {
|
||||||
@Override
|
Intent intent = new Intent(getApplicationContext(),
|
||||||
public void onClick(View v) {
|
StartConversationActivity.class);
|
||||||
if (mInitialAccountSetup) {
|
if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
|
||||||
Intent intent = new Intent(getApplicationContext(),
|
intent.putExtra("init", true);
|
||||||
StartConversationActivity.class);
|
|
||||||
if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
|
|
||||||
intent.putExtra("init", true);
|
|
||||||
}
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
}
|
||||||
finish();
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
finish();
|
||||||
});
|
});
|
||||||
this.avatar.setOnClickListener(new OnClickListener() {
|
this.avatar.setOnClickListener(v -> {
|
||||||
|
if (hasStoragePermission(REQUEST_CHOOSE_FILE)) {
|
||||||
@Override
|
chooseAvatar(false);
|
||||||
public void onClick(View v) {
|
|
||||||
if (hasStoragePermission(REQUEST_CHOOSE_FILE)) {
|
|
||||||
chooseAvatar(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
this.defaultUri = PhoneHelper.getProfilePictureUri(getApplicationContext());
|
this.defaultUri = PhoneHelper.getProfilePictureUri(getApplicationContext());
|
||||||
}
|
}
|
||||||
|
@ -153,7 +130,7 @@ public class PublishProfilePictureActivity extends XmppActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.length > 0)
|
||||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
if (requestCode == REQUEST_CHOOSE_FILE_AND_CROP) {
|
if (requestCode == REQUEST_CHOOSE_FILE_AND_CROP) {
|
||||||
|
@ -248,8 +225,7 @@ public class PublishProfilePictureActivity extends XmppActivity {
|
||||||
this.secondaryHint.setVisibility(View.INVISIBLE);
|
this.secondaryHint.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
if (!support) {
|
if (!support) {
|
||||||
this.hintOrWarning
|
this.hintOrWarning.setTextColor(getWarningTextColor());
|
||||||
.setTextColor(getWarningTextColor());
|
|
||||||
if (account.getStatus() == Account.State.ONLINE) {
|
if (account.getStatus() == Account.State.ONLINE) {
|
||||||
this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
|
this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
|
||||||
} else {
|
} else {
|
||||||
|
@ -264,13 +240,6 @@ public class PublishProfilePictureActivity extends XmppActivity {
|
||||||
} else {
|
} else {
|
||||||
loadImageIntoPreview(avatarUri);
|
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) {
|
if (bm == null) {
|
||||||
disablePublishButton();
|
disablePublishButton();
|
||||||
this.hintOrWarning.setTextColor(getWarningTextColor());
|
this.hintOrWarning.setTextColor(getWarningTextColor());
|
||||||
this.hintOrWarning
|
this.hintOrWarning.setText(R.string.error_publish_avatar_converting);
|
||||||
.setText(R.string.error_publish_avatar_converting);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.avatar.setImageBitmap(bm);
|
this.avatar.setImageBitmap(bm);
|
||||||
|
|
|
@ -84,14 +84,6 @@
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="8dp"
|
android:paddingLeft="8dp"
|
||||||
android:paddingRight="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
|
<TextView
|
||||||
android:id="@+id/hint_or_warning"
|
android:id="@+id/hint_or_warning"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
Loading…
Reference in a new issue