create avatar in background thread
This commit is contained in:
parent
9b95f1102c
commit
c58fcb1dc6
|
@ -8,6 +8,7 @@ import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
|
@ -465,16 +466,20 @@ public class FileBackend {
|
||||||
private void drawOverlay(Bitmap bitmap, int resource, float factor) {
|
private void drawOverlay(Bitmap bitmap, int resource, float factor) {
|
||||||
Bitmap overlay = BitmapFactory.decodeResource(mXmppConnectionService.getResources(), resource);
|
Bitmap overlay = BitmapFactory.decodeResource(mXmppConnectionService.getResources(), resource);
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
paint.setFilterBitmap(true);
|
|
||||||
paint.setDither(true);
|
|
||||||
float targetSize = Math.min(canvas.getWidth(), canvas.getHeight()) * factor;
|
float targetSize = Math.min(canvas.getWidth(), canvas.getHeight()) * factor;
|
||||||
Log.d(Config.LOGTAG, "target size overlay: " + targetSize + " overlay bitmap size was " + overlay.getHeight());
|
Log.d(Config.LOGTAG, "target size overlay: " + targetSize + " overlay bitmap size was " + overlay.getHeight());
|
||||||
float left = (canvas.getWidth() - targetSize) / 2.0f;
|
float left = (canvas.getWidth() - targetSize) / 2.0f;
|
||||||
float top = (canvas.getHeight() - targetSize) / 2.0f;
|
float top = (canvas.getHeight() - targetSize) / 2.0f;
|
||||||
RectF dst = new RectF(left, top, left + targetSize - 1, top + targetSize - 1);
|
RectF dst = new RectF(left, top, left + targetSize - 1, top + targetSize - 1);
|
||||||
canvas.drawBitmap(overlay,null,dst,paint);
|
canvas.drawBitmap(overlay, null, dst, createAntiAliasingPaint());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Paint createAntiAliasingPaint() {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setFilterBitmap(true);
|
||||||
|
paint.setDither(true);
|
||||||
|
return paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap getVideoPreview(File file, int size) {
|
private Bitmap getVideoPreview(File file, int size) {
|
||||||
|
@ -539,9 +544,26 @@ public class FileBackend {
|
||||||
if (bm == null) {
|
if (bm == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (hasAlpha(bm)) {
|
||||||
|
Log.d(Config.LOGTAG,"alpha in avatar detected; uploading as PNG");
|
||||||
|
bm.recycle();
|
||||||
|
bm = cropCenterSquare(image, 96);
|
||||||
|
return getPepAvatar(bm, Bitmap.CompressFormat.PNG, 100);
|
||||||
|
}
|
||||||
return getPepAvatar(bm, format, 100);
|
return getPepAvatar(bm, format, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean hasAlpha(final Bitmap bitmap) {
|
||||||
|
for(int x = 0; x < bitmap.getWidth(); ++x) {
|
||||||
|
for(int y = 0; y < bitmap.getWidth(); ++y) {
|
||||||
|
if (Color.alpha(bitmap.getPixel(x,y)) < 255) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private Avatar getPepAvatar(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {
|
private Avatar getPepAvatar(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
@ -554,7 +576,7 @@ public class FileBackend {
|
||||||
mDigestOutputStream.flush();
|
mDigestOutputStream.flush();
|
||||||
mDigestOutputStream.close();
|
mDigestOutputStream.close();
|
||||||
long chars = mByteArrayOutputStream.size();
|
long chars = mByteArrayOutputStream.size();
|
||||||
if (quality >= 50 && chars >= Config.AVATAR_CHAR_LIMIT) {
|
if (format != Bitmap.CompressFormat.PNG && quality >= 50 && chars >= Config.AVATAR_CHAR_LIMIT) {
|
||||||
int q = quality - 2;
|
int q = quality - 2;
|
||||||
Log.d(Config.LOGTAG, "avatar char length was " + chars + " reducing quality to " + q);
|
Log.d(Config.LOGTAG, "avatar char length was " + chars + " reducing quality to " + q);
|
||||||
return getPepAvatar(bitmap, format, q);
|
return getPepAvatar(bitmap, format, q);
|
||||||
|
@ -563,6 +585,15 @@ public class FileBackend {
|
||||||
final Avatar avatar = new Avatar();
|
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());
|
||||||
|
if (format.equals(Bitmap.CompressFormat.WEBP)) {
|
||||||
|
avatar.type = "image/webp";
|
||||||
|
} else if (format.equals(Bitmap.CompressFormat.JPEG)) {
|
||||||
|
avatar.type = "image/jpeg";
|
||||||
|
} else if (format.equals(Bitmap.CompressFormat.PNG)) {
|
||||||
|
avatar.type = "image/png";
|
||||||
|
}
|
||||||
|
avatar.width = bitmap.getWidth();
|
||||||
|
avatar.height = bitmap.getHeight();
|
||||||
return avatar;
|
return avatar;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -716,11 +747,7 @@ 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);
|
||||||
Paint p = new Paint();
|
canvas.drawBitmap(source, null, targetRect, createAntiAliasingPaint());
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -748,8 +775,8 @@ public class FileBackend {
|
||||||
|
|
||||||
Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||||
Canvas canvas = new Canvas(output);
|
Canvas canvas = new Canvas(output);
|
||||||
canvas.drawBitmap(input, null, target, null);
|
canvas.drawBitmap(input, null, target, createAntiAliasingPaint());
|
||||||
if (input != null && !input.isRecycled()) {
|
if (!input.isRecycled()) {
|
||||||
input.recycle();
|
input.recycle();
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -2808,20 +2808,12 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publishAvatar(Account account, Uri image, UiCallback<Avatar> callback) {
|
public void publishAvatar(final Account account, final Uri image, final UiCallback<Avatar> callback) {
|
||||||
|
new Thread(() -> {
|
||||||
final Bitmap.CompressFormat format = Config.AVATAR_FORMAT;
|
final Bitmap.CompressFormat format = Config.AVATAR_FORMAT;
|
||||||
final int size = Config.AVATAR_SIZE;
|
final int size = Config.AVATAR_SIZE;
|
||||||
final Avatar avatar = getFileBackend().getPepAvatar(image, size, format);
|
final Avatar avatar = getFileBackend().getPepAvatar(image, size, format);
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
avatar.height = size;
|
|
||||||
avatar.width = size;
|
|
||||||
if (format.equals(Bitmap.CompressFormat.WEBP)) {
|
|
||||||
avatar.type = "image/webp";
|
|
||||||
} else if (format.equals(Bitmap.CompressFormat.JPEG)) {
|
|
||||||
avatar.type = "image/jpeg";
|
|
||||||
} else if (format.equals(Bitmap.CompressFormat.PNG)) {
|
|
||||||
avatar.type = "image/png";
|
|
||||||
}
|
|
||||||
if (!getFileBackend().save(avatar)) {
|
if (!getFileBackend().save(avatar)) {
|
||||||
callback.error(R.string.error_saving_avatar, avatar);
|
callback.error(R.string.error_saving_avatar, avatar);
|
||||||
return;
|
return;
|
||||||
|
@ -2830,6 +2822,8 @@ public class XmppConnectionService extends Service {
|
||||||
} else {
|
} else {
|
||||||
callback.error(R.string.error_publish_avatar_converting, null);
|
callback.error(R.string.error_publish_avatar_converting, null);
|
||||||
}
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publishAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) {
|
public void publishAvatar(Account account, final Avatar avatar, final UiCallback<Avatar> callback) {
|
||||||
|
|
Loading…
Reference in New Issue