Reputation: 21763
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?
Upvotes: 2
Views: 2858
Reputation: 21763
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);
Upvotes: 2
Reputation: 3140
I have a set of images, loaded via Glide
From the above, I assume you are using RecyclerView
to show these images and my answer is based on this assumption.
Try it with a custom Glide target of your own that stops the animation if NSFW like this
public class CustomTarget extends GlideDrawableImageViewTarget {
private boolean isNSFW;
public CustomTarget(ImageView view) {
super(view);
}
public void setNSFW(boolean isNSFW){
this.isNSFW = isNSFW;
}
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
// this super call loads the image, sets it to the ImageView and starts
// animating if it is Gif
super.onResourceReady(resource, animation);
if(isNSFW){
onStop(); // stop playing the animation if NSFW
}
}
}
And in your View Holder class, create and keep a reference to this target as you would do for other views
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView myImageView;
CustomTarget myCustomTarget;
public MyViewHolder(View itemView) {
super(itemView);
myImageView = (ImageView) itemView.findViewById(R.id.myIv);
myCustomTarget = new CustomTarget(myImageView);
}
}
Then in onBindViewHolder do the following
public void onBindViewHolder(MyViewHolder holder, int position) {
// get the current entry in your image set
final Entry entry = entries.get(position);
// call this before loading the resource
holder.myCustomTarget.setNSFW(entry.isNSFW());
// No need to specify asGif()
// Refer http://stackoverflow.com/a/34870817/3533289
Glide.with(context)
.load(entry.getURL())
.into(holder.myCustomTarget);
}
I haven't tested this solution myself. But I hope it will give you an idea of how to tackle this issue.
Upvotes: 0