Last active
August 29, 2015 14:05
-
-
Save ronshapiro/efce6021ea63f786c8b1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.venmo.views; | |
import android.content.Context; | |
import android.content.res.Resources; | |
import android.graphics.Bitmap; | |
import android.graphics.BitmapShader; | |
import android.graphics.Canvas; | |
import android.graphics.Paint; | |
import android.graphics.drawable.BitmapDrawable; | |
import android.graphics.drawable.Drawable; | |
import android.support.annotation.DrawableRes; | |
import com.crashlytics.android.Crashlytics; | |
import com.google.common.cache.Cache; | |
import com.google.common.cache.CacheBuilder; | |
import com.squareup.picasso.Transformation; | |
public enum ResourceTransformation implements Transformation { | |
CIRCULAR_TRANSFORMATION() { | |
@Override | |
public Bitmap transform(Bitmap source, boolean recycle) { | |
int size = Math.min(source.getWidth(), source.getHeight()); | |
int x = (source.getWidth() - size) / 2; | |
int y = (source.getHeight() - size) / 2; | |
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size); | |
if (recycle && squaredBitmap != source) { | |
source.recycle(); | |
} | |
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); | |
Canvas canvas = new Canvas(bitmap); | |
Paint paint = new Paint(); | |
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, | |
BitmapShader.TileMode.CLAMP); | |
paint.setShader(shader); | |
paint.setAntiAlias(true); | |
float r = size / 2f; | |
canvas.drawCircle(r, r, r, paint); | |
if (recycle) { | |
squaredBitmap.recycle(); | |
} | |
return bitmap; | |
} | |
@Override | |
public String key() { | |
return "com.venmo.circle-transform"; | |
} | |
}; | |
public static final ResourceTransformation AVATAR_TRANSFORMATION = CIRCULAR_TRANSFORMATION; | |
private Cache<Integer, Drawable> mDrawableCache; | |
ResourceTransformation() { | |
mDrawableCache = CacheBuilder.newBuilder() | |
.maximumSize(10) | |
.build(); | |
} | |
@Override | |
public final Bitmap transform(Bitmap source) { | |
return transform(source, true); | |
} | |
/** | |
* @param recycle whether or not to recycle the source image. Useful for avoiding recycling a | |
* transformed Bitmap from {@link Resources}, since they are cached by the framework and could | |
* be used in other contexts, untransformed. | |
* @see Transformation#transform(Bitmap) | |
*/ | |
abstract Bitmap transform(Bitmap source, boolean recycle); | |
public Drawable transform(Context context, @DrawableRes int resId) { | |
Drawable cached = mDrawableCache.getIfPresent(resId); | |
if (cached == null) { | |
Resources res = context.getResources(); | |
Drawable drawable = res.getDrawable(resId); | |
if (drawable instanceof BitmapDrawable) { | |
Bitmap original = ((BitmapDrawable) drawable).getBitmap(); | |
Bitmap transformed = transform(original, false); | |
// Don't recycle `original` since those Bitmaps are cached by framework. Recycling | |
// it will cause any future references to that Drawable (even in XML) to be recycled. | |
drawable = new BitmapDrawable(res, transformed); | |
} else { | |
logNotBitmap(drawable); | |
} | |
mDrawableCache.put(resId, drawable); | |
return drawable; | |
} else { | |
return cached; | |
} | |
} | |
private void logNotBitmap(Drawable drawable) { | |
Crashlytics.logException(new IllegalStateException( | |
"Drawable expected to be BitmapDrawable but is " + drawable.getClass().getName() + | |
"instead!")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment