Nick Cardoso Nick Cardoso - 18 days ago 9
Android Question

Is there a way to force gif loaded with Glide to be non-animated

I have a set of images, loaded via Glide.

The NSFW ones are blurred using a glide (wasabeef) bitmap transformation, however some can be animated gifs, in which case the first frame is shown blurred, and then the animation starts looping (unblurred).

The following is what I have tried and does not work:

DrawableTypeRequest<String> builder = Glide.with(mImage.getContext()).load(...);

if (entry.isNsfw()) {
builder.asBitmap();
}

builder.diskCacheStrategy(DiskCacheStrategy.SOURCE) //it's likely none of this is relevant
.skipMemoryCache(true)
.override(props.getWidth(), props.getHeight());

if (entry.isNsfw()) {
//successfully blurs nsfw images, but still allows unblurred animation
builder.dontAnimate().bitmapTransform(centreCrop, blur);
} else {
builder.centerCrop();
}

builder.crossFade(500) //moving crossfade only into the sfw posts has no effect
.into(mImage);


Also not working is intercepting the load:

builder.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}

@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
if (entry.isNsfw()) {
target.onResourceReady(resource, null); //If I add this and return true the image is static, but unblurred
resource.stop(); //if this is called before target, it has no effect
return true;
}
return false; //returning true without calling the target stops any of the images being set on the view
}
});


How can I turn off the gif playback for individual images while still keeping the blur transformation?

Answer

In the end mixing a few of the steps I outlined in my question, fixed the issue. Animated NSFW gifs now display only the first frame, which is successfully blurred.

DrawableRequestBuilder<String> builder = Glide.with(ctx).load(...);
if (nsfw) {
    builder.bitmapTransform(new BlurTransformation(ctx, 8, 16), new CentreCrop(...));
} else {
    builder.centerCrop();
}
builder.listener(new RequestListener<String, GlideDrawable>() {
    ... //onException method
    @Override
    public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
        boolean handled = false;
        if (nsfw && resource.isAnimated()) {
            target.onResourceReady(new GlideBitmapDrawable(null, ((GifDrawable) resource).getFirstFrame()), null);
            handled = true; //glide now won't set the resource on the target itself
        }
        return handled;
    }
});
builder.crossFade(500).into(mImageView);