set add background color to glide image - android

I'm using Glide for setting png images (with transparencies) in ImageView in this mode:
Glide.with(context).load(url)
.crossFade()
.placeholder(R.drawable.no_contest)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into((ImageView)container);
Is it possible to set the backgroundcolor of the image without setting the background color of ImageView ?
thanks

LayerDrawable should be used:
.into(new SimpleTarget<GlideDrawable>() {
#Override
public void onResourceReady(GlideDrawable resource,
GlideAnimation<? super GlideDrawable> glideAnimation) {
final ShapeDrawable background = new ShapeDrawable();
background.getPaint().setColor("color here");
final Drawable[] layers = {background, resource};
container.setImageDrawable(new LayerDrawable(layers));
}
});

This will set background color according to your gif.
Glide code:
Glide.with(context).load(newspojo.getImageLink())
.asGif()
.listener(new RequestListener<String, GifDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GifDrawable> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(GifDrawable resource, String model, Target<GifDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
final Pojo pojo = new Pojo();
final GifDrawable resources = resource;
Palette.from(resource.getFirstFrame()).generate(new Palette.PaletteAsyncListener() {
#Override
public void onGenerated(#NonNull Palette palette) {
if (pojo.getPosterPalette() != null) {
setUpInfoBackgroundColor(holder.ivRow, palette);
} else {
Palette.from(resources.getFirstFrame()).generate(new Palette.PaletteAsyncListener() {
public void onGenerated(Palette palette) {
pojo.setPosterPalette(palette);
setUpInfoBackgroundColor(holder.ivRow, palette);
}
});
}
}
});
return false;
}
})
.into(holder.ivRow);
}
Here is Pojo:
public class Pojo {
public Palette posterPalette;
public Palette getPosterPalette() {
return posterPalette;
}
public void setPosterPalette(Palette posterPalette) {
this.posterPalette = posterPalette;
}
public Pojo(){
}
}
and add in build.gradle:
implementation 'com.android.support:palette-v7:27.1.1'

Related

Check if animation is completed Glide Android

I am using below listener code
.listener(new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
GifDrawable gifDrawable = null;
Handler handler = new Handler();
if (resource instanceof GifDrawable) {
gifDrawable = (GifDrawable) resource;
int duration = 0;
GifDecoder decoder = gifDrawable.getDecoder();
for (int i = 0; i < gifDrawable.getFrameCount(); i++) {
duration += decoder.getDelay(i);
}
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(intent);
SplashScreenActivity.this.finish();
}
}, (duration + 3000));
}
return false;
}
})
here I am not able to access getDecoder() at
GifDecoder decoder = gifDrawable.getDecoder();
How can I check if animation is completed. why getDecoder is not accessible here
I am using below glide dependency
implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
Thanks in Advance
Glide.with(context) // replace with 'this' if it's in activity
.load(url)
.into(new DrawableImageViewTarget(memeBackground) {
public void onResourceReady(Drawable resource, #Nullable Transition<? super Drawable> transition) {
if (resource instanceof GifDrawable) {
((GifDrawable) resource).registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
#Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
log.D("animation is completed");
}
});
super.onResourceReady(resource, transition);
}}});

Glide loader is not loading image properly

I am using Glide loader to load my images. My code is working but it changes images continuously. Here is my code:
Glide.with(ctx).load(image).asBitmap()
.dontTransform()
.placeholder(R.drawable.cart)
.into(new SimpleTarget < Bitmap > () {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
photoImageView.setImageBitmap(resource);
Glide.with(ctx).load(image).into(post_image);
post_image.setImageBitmap(resource);
}
Hey You can use glide utill class for better understanding
public class GlideUtil {
public static void loadImage(String url, ImageView imageView) {
Context context = imageView.getContext();
if(context!=null || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)) {
assert context != null;
ColorDrawable cd = new ColorDrawable(ContextCompat.getColor(context, R.color.blue_grey_500));
Glide.with(context)
.load(url)
.placeholder(cd)
.crossFade()
.centerCrop()
.into(imageView);
}
}
public static void loadProfileIcon(String url, ImageView imageView) {
Context context = imageView.getContext();
if(context!=null || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)) {
Glide.with(context)
.load(url)
.placeholder(R.drawable.ic_person_outline_black)
.dontAnimate()
.fitCenter()
.into(imageView);
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void loadImage(String url, ImageView mPhotoView, final ProgressBar mProgress) {
Context context = mPhotoView.getContext();
if(context!=null || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)) {
assert context != null;
ColorDrawable cd = new ColorDrawable(ContextCompat.getColor(context, R.color.blue_grey_500));
mProgress.setEnabled(true);
Glide.with(context)
.load(url)
.listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
mProgress.setVisibility(View.GONE);
return false;
}
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
mProgress.setVisibility(View.GONE);
return false;
}
})
.placeholder(cd)
.crossFade()
.centerCrop()
.into(mPhotoView);
}
}
}
Image changing occurs because of lazy loading of images in the glide. When the glide is downloading the new image previous image will be already loaded since you are reusing the view. To prevent this,.Before loading images clear the previous image before loading image.
Glide.clear(post_image);
EDIT:
Also before fetching the image from glide clear the old image of the imageView.
post_image.setImageDrawable(null);
Then load the new image from glide
Glide.with(ctx)
.load(image)
.asBitmap()
.dontTransform()
.placeholder(R.drawable.cart)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
post_image.setImageBitmap(resource);
}
}

Fading animation not working when an image is loaded with .asBitmap()

I have this code
Glide
.with(this)
.load(mUrl)
.asBitmap()
.thumbnail(Glide
.with(this)
.load(mPreviewUrl)
.asBitmap()
.animate(R.anim.fade_in))
.listener(new RequestListener<String, Bitmap>() {
#Override
public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
mProgressBar.setVisibility(View.GONE);
return false;
}
#Override
public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
mProgressBar.setVisibility(View.GONE);
return false;
}
})
.into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
mWallpaperImageView.setImageBitmap(resource);
createPaletteAsync(resource);
}
});
This downloads an image and returns a Bitmap object, which then I use to generate a palette of colour with the Palette library. I also want to load the bitmap in an ImageView, and I do that with mWallpaperImageView.setImageBitmap(resource) which loads the image without any fading or animation to smooth out the loading.
If I use glide like this:
Glide.with(this)
.load(mUrl)
.crossFade(500)
.into(mImageView)
then the image appears with fading but then I don't have a Bitmap object.
According to this answer,
Unfortunately, there isn't a built in way to cross fade Bitmaps. You
can however, use a custom BitmapImageViewTarget, and use a
TransitionDrawable in onResourceReady() to cross fade.
Fortunately, there's a trick to enable fading effect with bitmap in Glide.
For this you will need two classes,
FadingDrawable
final public class FadingDrawable extends BitmapDrawable {
// Only accessed from main thread.
private static final float FADE_DURATION = 200; //ms
private final float density;
Drawable placeholder;
long startTimeMillis;
boolean animating;
int alpha = 0xFF;
FadingDrawable(Context context, Bitmap bitmap, Drawable placeholder) {
super(context.getResources(), bitmap);
this.density = context.getResources().getDisplayMetrics().density;
this.placeholder = placeholder;
animating = true;
startTimeMillis = SystemClock.uptimeMillis();
}
/**
* Create or update the drawable on the target {#link android.widget.ImageView} to display the supplied bitmap
* image.
*/
static public void setBitmap(ImageView target, Context context, Bitmap bitmap) {
if (bitmap != null && !bitmap.isRecycled()) {
Drawable placeholder = target.getDrawable();
if (placeholder instanceof AnimationDrawable) {
((AnimationDrawable) placeholder).stop();
}
FadingDrawable drawable = new FadingDrawable(context, bitmap, placeholder);
//this will avoid OverDraw
//target.setBackgroundDrawable(null);
//target.setBackgroundColor(0);
target.setImageDrawable(drawable);
}
}
/**
* Create or update the drawable on the target {#link android.widget.ImageView} to display the supplied
* placeholder image.
*/
static void setPlaceholder(ImageView target, Drawable placeholderDrawable) {
target.setImageDrawable(placeholderDrawable);
if (target.getDrawable() instanceof AnimationDrawable) {
((AnimationDrawable) target.getDrawable()).start();
}
}
#Override
public void draw(Canvas canvas) {
if (!animating) {
super.draw(canvas);
} else {
float normalized = (SystemClock.uptimeMillis() - startTimeMillis) / FADE_DURATION;
if (normalized >= 1f) {
animating = false;
placeholder = null;
super.draw(canvas);
} else {
if (placeholder != null) {
placeholder.draw(canvas);
}
int partialAlpha = (int) (alpha * normalized);
super.setAlpha(partialAlpha);
super.draw(canvas);
super.setAlpha(alpha);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
invalidateSelf();
}
}
}
}
#Override
public void setAlpha(int alpha) {
this.alpha = alpha;
if (placeholder != null) {
placeholder.setAlpha(alpha);
}
super.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
if (placeholder != null) {
placeholder.setColorFilter(cf);
}
super.setColorFilter(cf);
}
#Override
protected void onBoundsChange(Rect bounds) {
if (placeholder != null) {
placeholder.setBounds(bounds);
}
super.onBoundsChange(bounds);
}
}
and GlideImageView
public class GlideImageView extends AppCompatImageView {
public GlideImageView(Context context) {
this(context, null);
}
public GlideImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GlideImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Drawable placeholder = getDrawable();
if (placeholder instanceof AnimationDrawable) {
((AnimationDrawable) placeholder).stop();
Glide.clear(this);
}
}
#Override
public void setImageBitmap(Bitmap bitmap) {
if (bitmap != null) FadingDrawable.setBitmap(this, getContext(), bitmap);
}
public void setImageBitmapWithoutAnimation(Bitmap bitmap) {
super.setImageBitmap(bitmap);
}
}
Now change your mWallpaperImageView from ImageView to
<com.yourpackage.GlideImageView
android:id="#+id/mWallpaperImageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And finally remove all external animation effect from Glide configuration,
Glide
.with(this)
.load(mUrl)
.asBitmap()
.thumbnail(Glide
.with(this)
.load(mPreviewUrl)
.asBitmap()
.listener(new RequestListener<String, Bitmap>() {
#Override
public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
mProgressBar.setVisibility(View.GONE);
return false;
}
#Override
public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
mProgressBar.setVisibility(View.GONE);
return false;
}
})
.into(new SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
mWallpaperImageView.setImageBitmap(resource);
createPaletteAsync(resource);
}
});
Tested and working properly!
You can use the value of the alpha of an image to create a fade in or fade out effect:
In Java
yourimage.animate().setAlpha(0f).setDuration(2000);
given that the image's alpha starts with alpha =1 (not transparent).
so the image will disappear (transparent) during 2 seconds

Save image once Glide has loaded it

I load images using Glide like such:
Glide.with(getContext()).load(apdInfo.url)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(apd_image);
And wish to save the Bitmap loaded like such:
private void saveImage() {
final ImageView apd_image = (ImageView) view.findViewById(R.id.apd_image);
final InternalFileHandler IFH = new InternalFileHandler(getContext());
apd_image.setDrawingCacheEnabled(true);
apd_image.buildDrawingCache(true);
Bitmap bitmap = apd_image.getDrawingCache();
// Simply saves the bitmap in the filesystem
IFH.savePicture("APD", bitmap, getContext());
apd_image.destroyDrawingCache();
}
The issue is that if I call saveImage before Glide has loaded my picture, it won't work.
How may I wait or Glide to load it? Please note that using Glide's listeners did not work.
EDIT:
I now use the following listeners:
.listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
//handle the exception.
return true;
}
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
// onResourceReady is called twice for some reason, this is my work around for now
if (first) {
GlideBitmapDrawable glideBitmapDrawable = (GlideBitmapDrawable) resource;
// Convert to Bitmap
Bitmap bm = glideBitmapDrawable.getBitmap();
saveImage(bm);
first = false;
} else {
first = true;
}
return true;
}
})
Use the listener so that when the image is fetched and ready to be used, you can save it using the saveImage method of yours.
Do this:
Glide.with(getContext()).load(apdInfo.url)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(new SimpleTarget<GlideDrawable>() {
#Override
public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation) {
apd_image.setImageDrawable(glideDrawable);
apd_image.setDrawingCacheEnabled(true);
saveImage();
}});
Call the saveImage method inside onResourceReady() callback and use the GlideDrawable resource. I would suggest using the GlideDrawable rather than getting the image using Drawing Cache.

Glide: onError Callback

I'm switching from Picasso to Glide. Everything works fine except I cannot find a method to get an error callback. I want to retrieve a Bitmap, pass it on and generate an Android Palette from it. Also, while an errorDrawable can be provided to a load call, it won't show up in onResourceReady when using a SimpleTarget.
In Picasso I did it like this:
target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
//handle Bitmap, generate Palette etc.
}
#Override
public void onBitmapFailed(final Drawable errorDrawable) {
// use errorDrawable to generate Palette
}
#Override
public void onPrepareLoad(final Drawable placeHolderDrawable) {
}
};
int width = (int) DisplayUnitsConverter.dpToPx(this, 120);
int height = (int) DisplayUnitsConverter.dpToPx(this, 40);
Picasso.with(this).load(config.getPathToLogo()).resize(width, height).error(errorDrawableId).into(target);
My glide code looks like this:
Glide.with(context)
.load(config.getPathToLogo())
.asBitmap()
.into(new SimpleTarget<Bitmap>(width, height) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
//handle Bitmap, generate Palette etc.
}
});
Thanks.
For everyone with the same problem - you need to use listener method. For example:
Glide.with(activity)
.load(getPhoto().getUrl())
.apply(
new RequestOptions()
.error(R.drawable.icon_placeholder)
.centerCrop()
)
.listener(new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
//on load failed
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
//on load success
return false;
}
})
.transition(withCrossFade())
.into(view);
You are using SimpleTarget that implements the interface Target that defines the method onLoadFailed so you only need to do:
Glide.with(context)
.load(config.getPathToLogo())
.asBitmap()
.into(new SimpleTarget<Bitmap>(width, height) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
//handle Bitmap, generate Palette etc.
}
#Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
// Do something.
}
});

Categories

Resources