rounded ImageView instead of Bitmap, crop-select

// FREEBIE
master
Jake McGinty 2014-12-29 17:31:41 -08:00
parent a0599c1639
commit 62816ee51a
19 changed files with 81 additions and 154 deletions

View File

@ -212,6 +212,8 @@
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name="com.soundcloud.android.crop.CropImageActivity" />
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
<service android:enabled="true" android:name=".service.KeyCachingService"/>
<service android:enabled="true" android:name=".service.RegistrationService"/>

View File

@ -40,6 +40,8 @@ dependencies {
compile 'org.w3c:smil:1.0.0'
compile 'org.apache.httpcomponents:httpclient-android:4.3.5'
compile 'com.github.chrisbanes.photoview:library:1.2.3'
compile 'com.makeramen:roundedimageview:1.5.0'
compile 'com.soundcloud.android:android-crop:0.9.10@aar'
compile 'com.android.support:appcompat-v7:20.0.0'
compile 'com.madgag.spongycastle:prov:1.51.0.0'
compile 'com.google.zxing:android-integration:3.1.0'
@ -71,6 +73,8 @@ dependencyVerification {
'org.w3c:smil:085dc40f2bb249651578bfa07499fd08b16ad0886dbe2c4078586a408da62f9b',
'org.apache.httpcomponents:httpclient-android:6f56466a9bd0d42934b90bfbfe9977a8b654c058bf44a12bdc2877c4e1f033f1',
'com.github.chrisbanes.photoview:library:8b5344e206f125e7ba9d684008f36c4992d03853c57e5814125f88496126e3cc',
'com.makeramen:roundedimageview:7dda2e78c406760e5c356ccce59b0df46b5b171cf18abb891998594405021548',
'com.soundcloud.android:android-crop:ffd4b973cf6e97f7d64118a0dc088df50e9066fd5634fe6911dd0c0c5d346177',
'com.android.support:appcompat-v7:736f576ab0b68d27bdf18b1e7931566e6d8254b73965175313e87f8866b91547',
'com.madgag.spongycastle:prov:b8c3fec3a59aac1aa04ccf4dad7179351e54ef7672f53f508151b614c131398a',
'com.google.zxing:android-integration:89e56aadf1164bd71e57949163c53abf90af368b51669c0d4a47a163335f95c4',

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.ConversationItem android:id="@+id/conversation_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingRight="10dip"
android:orientation="vertical"
android:background="?conversation_item_background"
xmlns:android="http://schemas.android.com/apk/res/android">
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingRight="10dip"
android:orientation="vertical"
android:background="?conversation_item_background"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView android:id="@+id/group_message_status"
android:layout_width="wrap_content"
@ -26,11 +27,12 @@
android:layout_marginRight="0dp"
android:orientation="horizontal">
<org.thoughtcrime.securesms.components.ForegroundImageView
<com.makeramen.RoundedImageView
android:id="@+id/contact_photo"
android:foreground="@drawable/contact_photo_background"
android:layout_width="40dp"
android:layout_height="40dp"
app:riv_oval="true"
android:layout_marginRight="10dp"
android:layout_alignParentLeft="true"
android:cropToPadding="true"

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.ConversationListItem
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -15,11 +16,12 @@
android:paddingRight="10dp"
android:visibility="visible">
<org.thoughtcrime.securesms.components.ForegroundImageView
<com.makeramen.RoundedImageView
android:id="@+id/contact_photo_image"
android:foreground="@drawable/contact_photo_background"
android:layout_width="60dp"
android:layout_height="60dp"
app:riv_oval="true"
android:cropToPadding="true"
android:scaleType="centerCrop"
android:visibility="gone"

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="fill_parent"
@ -24,6 +25,7 @@
android:layout_width="70dp"
android:layout_height="70dp"
position="bottom_right"
app:riv_oval="true"
android:layout_marginRight="10dp"
android:src="@drawable/ic_group_photo"
android:contentDescription="@string/GroupCreateActivity_avatar_content_description" />

View File

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingRight="25dip">
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingRight="25dip">
<ImageView android:id="@+id/contact_photo_image"
<com.makeramen.RoundedImageView
android:id="@+id/contact_photo_image"
android:layout_width="@dimen/contact_selection_photo_size"
android:layout_height="@dimen/contact_selection_photo_size"
android:layout_alignParentLeft="true"
@ -13,6 +15,7 @@
android:layout_marginLeft="10dp"
android:cropToPadding="true"
android:scaleType="centerCrop"
app:riv_oval="true"
android:contentDescription="@string/SingleContactSelectionActivity_contact_photo" />
<TextView android:id="@+id/number"

View File

@ -590,10 +590,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else if (isGroupConversation()) {
if (isPushGroupConversation()) {
final String groupName = recipient.getName();
final Bitmap avatar = recipient.getContactPhoto();
if (avatar != null) {
getSupportActionBar().setIcon(new BitmapDrawable(getResources(), BitmapUtil.getCircleCroppedBitmap(avatar)));
}
title = (!TextUtils.isEmpty(groupName)) ? groupName : getString(R.string.ConversationActivity_unnamed_group);
subtitle = null;

View File

@ -439,7 +439,7 @@ public class ConversationItem extends LinearLayout {
if ((recipient.getContactPhoto() == ContactPhotoFactory.getDefaultContactPhoto(context)) && (groupThread)) {
contactPhotoBitmap = recipient.getGeneratedAvatar(context);
} else {
contactPhotoBitmap = recipient.getCircleCroppedContactPhoto();
contactPhotoBitmap = recipient.getContactPhoto();
}
contactPhoto.setImageBitmap(contactPhotoBitmap);

View File

@ -128,7 +128,7 @@ public class ConversationListItem extends RelativeLayout
private void setContactPhoto(final Recipient recipient) {
if (recipient == null) return;
contactPhotoImage.setImageBitmap(recipient.getCircleCroppedContactPhoto());
contactPhotoImage.setImageBitmap(recipient.getContactPhoto());
if (!recipient.isGroupRecipient()) {
contactPhotoImage.setOnClickListener(new View.OnClickListener() {

View File

@ -40,6 +40,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.google.protobuf.ByteString;
import com.soundcloud.android.crop.Crop;
import org.thoughtcrime.securesms.components.PushRecipientsPanel;
import org.thoughtcrime.securesms.contacts.ContactAccessor;
@ -68,6 +69,7 @@ import org.thoughtcrime.securesms.database.NotInDirectoryException;
import org.whispersystems.textsecure.api.util.InvalidNumberException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
@ -282,9 +284,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
avatar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT, null);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, PICK_AVATAR);
Crop.pickImage(GroupCreateActivity.this);
}
});
@ -373,6 +373,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
Uri outputFile = Uri.fromFile(new File(getCacheDir(), "cropped"));
if (data == null || resultCode != Activity.RESULT_OK)
return;
@ -398,9 +399,11 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
syncAdapterWithSelectedContacts();
break;
case PICK_AVATAR:
new DecodeCropAndSetAsyncTask(data.getData()).execute();
case Crop.REQUEST_PICK:
new Crop(data.getData()).output(outputFile).asSquare().start(this);
break;
case Crop.REQUEST_CROP:
new DecodeCropAndSetAsyncTask(Crop.getOutput(data)).execute();
}
}
@ -510,7 +513,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
protected Bitmap doInBackground(Void... voids) {
if (avatarUri != null) {
try {
avatarBmp = BitmapUtil.getScaledCircleCroppedBitmap(GroupCreateActivity.this, masterSecret, avatarUri, AVATAR_SIZE);
avatarBmp = BitmapUtil.createScaledBitmap(GroupCreateActivity.this, masterSecret, avatarUri, AVATAR_SIZE, AVATAR_SIZE);
} catch (IOException | BitmapDecodingException e) {
Log.w(TAG, e);
return null;
@ -683,8 +686,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
existingTitle = group.getTitle();
final byte[] existingAvatar = group.getAvatar();
if (existingAvatar != null) {
existingAvatarBmp = BitmapUtil.getCircleCroppedBitmap(
BitmapFactory.decodeByteArray(existingAvatar, 0, existingAvatar.length));
existingAvatarBmp = BitmapFactory.decodeByteArray(existingAvatar, 0, existingAvatar.length);
}
}
return null;

View File

@ -98,7 +98,7 @@ public class ShareListItem extends RelativeLayout
private void setContactPhoto(final Recipient recipient) {
if (recipient == null) return;
contactPhotoImage.setImageBitmap(BitmapUtil.getCircleCroppedBitmap(recipient.getContactPhoto()));
contactPhotoImage.setImageBitmap(recipient.getContactPhoto());
}
private void setBackground() {

View File

@ -1,16 +1,17 @@
package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.makeramen.RoundedImageView;
import org.thoughtcrime.securesms.R;
public class ImageDivet extends ImageView {
public class ImageDivet extends RoundedImageView {
private static final float CORNER_OFFSET = 12F;
private static final String[] POSITIONS = new String[] {"bottom_right"};

View File

@ -19,15 +19,11 @@ import java.util.Map;
public class ContactPhotoFactory {
private static final Object defaultPhotoLock = new Object();
private static final Object defaultGroupPhotoLock = new Object();
private static final Object defaultPhotoCroppedLock = new Object();
private static final Object defaultGroupPhotoCroppedLock = new Object();
private static final Object defaultPhotoLock = new Object();
private static final Object defaultGroupPhotoLock = new Object();
private static Bitmap defaultContactPhoto;
private static Bitmap defaultGroupContactPhoto;
private static Bitmap defaultContactPhotoCropped;
private static Bitmap defaultGroupContactPhotoCropped;
private static final Map<Uri,Bitmap> localUserContactPhotoCache =
Collections.synchronizedMap(new LRUCache<Uri,Bitmap>(2));
@ -56,24 +52,6 @@ public class ContactPhotoFactory {
}
}
public static Bitmap getDefaultContactPhotoCropped(Context context) {
synchronized (defaultPhotoCroppedLock) {
if (defaultContactPhotoCropped == null)
defaultContactPhotoCropped = BitmapUtil.getCircleCroppedBitmap(getDefaultContactPhoto(context));
return defaultContactPhotoCropped;
}
}
public static Bitmap getDefaultGroupPhotoCropped(Context context) {
synchronized (defaultGroupPhotoCroppedLock) {
if (defaultGroupContactPhotoCropped == null)
defaultGroupContactPhotoCropped = BitmapUtil.getCircleCroppedBitmap(getDefaultGroupPhoto(context));
return defaultGroupContactPhotoCropped;
}
}
public static Bitmap getLocalUserContactPhoto(Context context, Uri uri) {
if (uri == null) return getDefaultContactPhoto(context);

View File

@ -30,12 +30,10 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.FilterQueryProvider;
import android.widget.ImageView;
import android.widget.TextView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.BitmapWorkerRunnable;
import org.thoughtcrime.securesms.util.BitmapWorkerRunnable.AsyncDrawable;
import org.thoughtcrime.securesms.util.TaggedFutureTask;
@ -76,10 +74,9 @@ public class ContactSelectionListAdapter extends CursorAdapter
private final LayoutInflater li;
private final TypedArray drawables;
private final Bitmap defaultPhoto;
private final Bitmap defaultCroppedPhoto;
private final int scaledPhotoSize;
private final HashMap<Long, ContactAccessor.ContactData> selectedContacts = new HashMap<Long, ContactAccessor.ContactData>();
private final HashMap<Long, ContactAccessor.ContactData> selectedContacts = new HashMap<>();
public ContactSelectionListAdapter(Context context, Cursor cursor, boolean multiSelect) {
super(context, cursor, 0);
@ -89,7 +86,6 @@ public class ContactSelectionListAdapter extends CursorAdapter
this.multiSelect = multiSelect;
this.defaultPhoto = ContactPhotoFactory.getDefaultContactPhoto(context);
this.scaledPhotoSize = context.getResources().getDimensionPixelSize(R.dimen.contact_selection_photo_size);
this.defaultCroppedPhoto = BitmapUtil.getScaledCircleCroppedBitmap(defaultPhoto, scaledPhotoSize);
}
public static class ViewHolder {
@ -184,7 +180,7 @@ public class ContactSelectionListAdapter extends CursorAdapter
numberLabelSpan.setSpan(new ForegroundColorSpan(drawables.getColor(2, 0xff444444)), contactData.number.length(), numberWithLabel.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
holder.number.setText(numberLabelSpan);
}
holder.contactPhoto.setImageBitmap(defaultCroppedPhoto);
holder.contactPhoto.setImageBitmap(defaultPhoto);
if (contactData.id > -1) loadBitmap(contactData.number, holder.contactPhoto);
}
@ -237,7 +233,7 @@ public class ContactSelectionListAdapter extends CursorAdapter
if (cancelPotentialWork(number, imageView)) {
final BitmapWorkerRunnable runnable = new BitmapWorkerRunnable(context, imageView, defaultPhoto, number, scaledPhotoSize);
final TaggedFutureTask<?> task = new TaggedFutureTask<Void>(runnable, null, number);
final AsyncDrawable asyncDrawable = new AsyncDrawable(context.getResources(), defaultCroppedPhoto, task);
final AsyncDrawable asyncDrawable = new AsyncDrawable(defaultPhoto, task);
imageView.setImageDrawable(asyncDrawable);
if (!task.isCancelled()) photoResolver.execute(new FutureTask<Void>(task, null));

View File

@ -24,7 +24,7 @@ public class AvatarGenerator {
public static Bitmap generateFor(Context context, Recipient recipient) {
if ((recipient == null) || (recipient.getName() == null)) {
return BitmapUtil.getCircleCroppedBitmap(ContactPhotoFactory.getDefaultContactPhoto(context));
return ContactPhotoFactory.getDefaultContactPhoto(context);
}
final int size = ContactPhotoFactory.getDefaultContactPhoto(context).getHeight();

View File

@ -41,16 +41,14 @@ public class Recipient {
private String name;
private Bitmap contactPhoto;
private Bitmap circleCroppedContactPhoto;
private Bitmap generatedAvatar;
private Uri contactUri;
Recipient(String number, Bitmap contactPhoto, Bitmap circleCroppedContactPhoto,
Recipient(String number, Bitmap contactPhoto,
long recipientId, ListenableFutureTask<RecipientDetails> future)
{
this.number = number;
this.circleCroppedContactPhoto = circleCroppedContactPhoto;
this.contactPhoto = contactPhoto;
this.recipientId = recipientId;
this.generatedAvatar = null;
@ -66,8 +64,7 @@ public class Recipient {
Recipient.this.number = result.number;
Recipient.this.contactUri = result.contactUri;
Recipient.this.contactPhoto = result.avatar;
Recipient.this.circleCroppedContactPhoto = result.croppedAvatar;
localListeners = (HashSet<RecipientModifiedListener>) listeners.clone();
listeners.clear();
}
@ -84,15 +81,12 @@ public class Recipient {
});
}
Recipient(String name, String number, long recipientId, Uri contactUri, Bitmap contactPhoto,
Bitmap circleCroppedContactPhoto)
{
Recipient(String name, String number, long recipientId, Uri contactUri, Bitmap contactPhoto) {
this.number = number;
this.recipientId = recipientId;
this.contactUri = contactUri;
this.name = name;
this.contactPhoto = contactPhoto;
this.circleCroppedContactPhoto = circleCroppedContactPhoto;
}
public synchronized Uri getContactUri() {
@ -153,10 +147,6 @@ public class Recipient {
return contactPhoto;
}
public synchronized Bitmap getCircleCroppedContactPhoto() {
return this.circleCroppedContactPhoto;
}
public synchronized Bitmap getGeneratedAvatar(Context context) {
if (this.generatedAvatar == null)
this.generatedAvatar = AvatarGenerator.generateFor(context, this);
@ -166,8 +156,7 @@ public class Recipient {
public static Recipient getUnknownRecipient(Context context) {
return new Recipient("Unknown", "Unknown", -1, null,
ContactPhotoFactory.getDefaultContactPhoto(context),
ContactPhotoFactory.getDefaultContactPhotoCropped(context));
ContactPhotoFactory.getDefaultContactPhoto(context));
}
@Override

View File

@ -73,17 +73,13 @@ public class RecipientProvider {
else details = getRecipientDetails(context, number);
if (details != null) {
recipient = new Recipient(details.name, details.number, recipientId, details.contactUri, details.avatar,
details.croppedAvatar);
recipient = new Recipient(details.name, details.number, recipientId, details.contactUri, details.avatar);
} else {
final Bitmap defaultPhoto = isGroupRecipient
? ContactPhotoFactory.getDefaultGroupPhoto(context)
: ContactPhotoFactory.getDefaultContactPhoto(context);
final Bitmap defaultCroppedPhoto = isGroupRecipient
? ContactPhotoFactory.getDefaultGroupPhotoCropped(context)
: ContactPhotoFactory.getDefaultContactPhotoCropped(context);
recipient = new Recipient(null, number, recipientId, null, defaultPhoto, defaultCroppedPhoto);
recipient = new Recipient(null, number, recipientId, null, defaultPhoto);
}
recipientCache.put(recipientId, recipient);
@ -109,17 +105,14 @@ public class RecipientProvider {
asyncRecipientResolver.submit(future);
Bitmap contactPhoto;
Bitmap contactPhotoCropped;
if (isGroupRecipient) {
contactPhoto = ContactPhotoFactory.getDefaultGroupPhoto(context);
contactPhotoCropped = ContactPhotoFactory.getDefaultGroupPhotoCropped(context);
} else {
contactPhoto = ContactPhotoFactory.getDefaultContactPhoto(context);
contactPhotoCropped = ContactPhotoFactory.getDefaultContactPhotoCropped(context);
}
Recipient recipient = new Recipient(number, contactPhoto, contactPhotoCropped, recipientId, future);
Recipient recipient = new Recipient(number, contactPhoto, recipientId, future);
recipientCache.put(recipientId, recipient);
return recipient;
@ -144,8 +137,7 @@ public class RecipientProvider {
Uri contactUri = Contacts.getLookupUri(cursor.getLong(2), cursor.getString(1));
Bitmap contactPhoto = ContactPhotoFactory.getContactPhoto(context, Uri.withAppendedPath(Contacts.CONTENT_URI,
cursor.getLong(2)+""));
return new RecipientDetails(cursor.getString(0), cursor.getString(3), contactUri, contactPhoto,
BitmapUtil.getCircleCroppedBitmap(contactPhoto));
return new RecipientDetails(cursor.getString(0), cursor.getString(3), contactUri, contactPhoto);
}
} finally {
if (cursor != null)
@ -167,7 +159,7 @@ public class RecipientProvider {
if (avatarBytes == null) avatar = ContactPhotoFactory.getDefaultGroupPhoto(context);
else avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length);
return new RecipientDetails(record.getTitle(), groupId, null, avatar, BitmapUtil.getCircleCroppedBitmap(avatar));
return new RecipientDetails(record.getTitle(), groupId, null, avatar);
}
return null;
@ -181,14 +173,12 @@ public class RecipientProvider {
public final String name;
public final String number;
public final Bitmap avatar;
public final Bitmap croppedAvatar;
public final Uri contactUri;
public RecipientDetails(String name, String number, Uri contactUri, Bitmap avatar, Bitmap croppedAvatar) {
public RecipientDetails(String name, String number, Uri contactUri, Bitmap avatar) {
this.name = name;
this.number = number;
this.avatar = avatar;
this.croppedAvatar = croppedAvatar;
this.contactUri = contactUri;
}
}

View File

@ -217,41 +217,6 @@ public class BitmapUtil {
return new Pair<>(options.outWidth, options.outHeight);
}
public static Bitmap getCircleCroppedBitmap(Bitmap bitmap) {
if (bitmap == null) return null;
final int srcSize = Math.min(bitmap.getWidth(), bitmap.getHeight());
return getScaledCircleCroppedBitmap(bitmap, srcSize);
}
public static Bitmap getScaledCircleCroppedBitmap(Context context, MasterSecret masterSecret, Uri uri, int destSize)
throws IOException, BitmapDecodingException
{
Bitmap bitmap = createScaledBitmap(context, masterSecret, uri, destSize, destSize);
return getScaledCircleCroppedBitmap(bitmap, destSize);
}
public static Bitmap getScaledCircleCroppedBitmap(Bitmap bitmap, int destSize) {
if (bitmap == null) return null;
Bitmap output = Bitmap.createBitmap(destSize, destSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int srcSize = Math.min(bitmap.getWidth(), bitmap.getHeight());
final int srcX = (bitmap.getWidth() - srcSize) / 2;
final int srcY = (bitmap.getHeight() - srcSize) / 2;
final Rect srcRect = new Rect(srcX, srcY, srcX + srcSize, srcY + srcSize);
final Rect destRect = new Rect(0, 0, destSize, destSize);
final int color = 0xff424242;
final Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(destSize / 2, destSize / 2, destSize / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, srcRect, destRect, paint);
return output;
}
public static InputStream toCompressedJpeg(Bitmap bitmap) {
ByteArrayOutputStream thumbnailBytes = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 85, thumbnailBytes);

View File

@ -25,6 +25,8 @@ import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.ImageView;
import com.makeramen.RoundedDrawable;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
@ -48,7 +50,7 @@ public class BitmapWorkerRunnable implements Runnable {
public final String number;
public BitmapWorkerRunnable(Context context, ImageView imageView, Bitmap defaultPhoto, String number, int size) {
this.imageViewReference = new WeakReference<ImageView>(imageView);
this.imageViewReference = new WeakReference<>(imageView);
this.context = context;
this.defaultPhoto = defaultPhoto;
this.size = size;
@ -57,42 +59,36 @@ public class BitmapWorkerRunnable implements Runnable {
@Override
public void run() {
final Bitmap bitmap;
try {
final Recipient recipient = RecipientFactory.getRecipientsFromString(context, number, false).getPrimaryRecipient();
final Bitmap contactPhoto = recipient.getContactPhoto();
if (defaultPhoto == contactPhoto) {
return;
}
if (recipient.getContactPhoto() != null) {
final ImageView imageView = imageViewReference.get();
final TaggedFutureTask<?> bitmapWorkerTask = AsyncDrawable.getBitmapWorkerTask(imageView);
bitmap = BitmapUtil.getScaledCircleCroppedBitmap(contactPhoto, size);
if (bitmapWorkerTask.getTag().equals(number) && imageView != null) {
final BitmapDrawable drawable = new BitmapDrawable(context.getResources(), recipient.getContactPhoto());
imageView.post(new Runnable() {
@Override
public void run() {
imageView.setImageDrawable(drawable);
}
});
}
}
} catch (RecipientFormattingException rfe) {
Log.w(TAG, "Couldn't get recipient from string", rfe);
return;
}
if (bitmap != null) {
final ImageView imageView = imageViewReference.get();
final TaggedFutureTask<?> bitmapWorkerTask = AsyncDrawable.getBitmapWorkerTask(imageView);
if (bitmapWorkerTask.getTag().equals(number) && imageView != null) {
final BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap);
imageView.post(new Runnable() {
@Override
public void run() {
imageView.setImageDrawable(drawable);
}
});
}
}
}
public static class AsyncDrawable extends BitmapDrawable {
public static class AsyncDrawable extends RoundedDrawable {
private final WeakReference<TaggedFutureTask<?>> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
TaggedFutureTask<?> bitmapWorkerTask) {
super(res, bitmap);
public AsyncDrawable(Bitmap bitmap, TaggedFutureTask<?> bitmapWorkerTask) {
super(bitmap);
bitmapWorkerTaskReference =
new WeakReference<TaggedFutureTask<?>>(bitmapWorkerTask);
}
@ -112,5 +108,4 @@ public class BitmapWorkerRunnable implements Runnable {
return null;
}
}
}