com.bumptech.glide.load.resource.bitmap.DrawableTransformation Maven / Gradle / Ivy
Show all versions of glide Show documentation
package com.bumptech.glide.load.resource.bitmap;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import java.security.MessageDigest;
/**
* Applies a {@link Bitmap} {@link Transformation} to {@link Drawable}s by first attempting to
* convert the {@link Drawable} to a {@link Bitmap} and then running the {@link Transformation} on
* the converted {@link Bitmap}.
*
* This class is relatively efficient for {@link BitmapDrawable} where the {@link Bitmap} is
* readily accessible. For non-{@link Bitmap} based {@link Drawable}s, this class must first try to
* draw the {@link Drawable} to a {@link Bitmap} using {@link android.graphics.Canvas}, which is
* less efficient. {@link Drawable}s that implement {@link android.graphics.drawable.Animatable}
* will fail with an exception. {@link Drawable}s that return <= 0 for {@link
* Drawable#getIntrinsicHeight()} and/or {@link Drawable#getIntrinsicWidth()} will fail with an
* exception if the requested size is {@link
* com.bumptech.glide.request.target.Target#SIZE_ORIGINAL}. {@link Drawable}s without intrinsic
* dimensions are drawn using the dimensions provided in {@link Transformation#transform(Context,
* Resource, int, int)}. As a result, they may be transformed incorrectly or in unexpected ways.
*/
public class DrawableTransformation implements Transformation {
private final Transformation wrapped;
private final boolean isRequired;
public DrawableTransformation(Transformation wrapped, boolean isRequired) {
this.wrapped = wrapped;
this.isRequired = isRequired;
}
@SuppressWarnings("unchecked")
public Transformation asBitmapDrawable() {
return (Transformation) (Transformation>) this;
}
@NonNull
@Override
public Resource transform(
@NonNull Context context, @NonNull Resource resource, int outWidth, int outHeight) {
BitmapPool bitmapPool = Glide.get(context).getBitmapPool();
Drawable drawable = resource.get();
Resource bitmapResourceToTransform =
DrawableToBitmapConverter.convert(bitmapPool, drawable, outWidth, outHeight);
if (bitmapResourceToTransform == null) {
if (isRequired) {
throw new IllegalArgumentException("Unable to convert " + drawable + " to a Bitmap");
} else {
return resource;
}
}
Resource transformedBitmapResource =
wrapped.transform(context, bitmapResourceToTransform, outWidth, outHeight);
if (transformedBitmapResource.equals(bitmapResourceToTransform)) {
transformedBitmapResource.recycle();
return resource;
} else {
return newDrawableResource(context, transformedBitmapResource);
}
}
// It's clearer to cast the result in a separate line from obtaining it.
@SuppressWarnings({"unchecked", "PMD.UnnecessaryLocalBeforeReturn"})
private Resource newDrawableResource(Context context, Resource transformed) {
Resource extends Drawable> result =
LazyBitmapDrawableResource.obtain(context.getResources(), transformed);
return (Resource) result;
}
@Override
public boolean equals(Object o) {
if (o instanceof DrawableTransformation) {
DrawableTransformation other = (DrawableTransformation) o;
return wrapped.equals(other.wrapped);
}
return false;
}
@Override
public int hashCode() {
return wrapped.hashCode();
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
wrapped.updateDiskCacheKey(messageDigest);
}
}