4

I have image files(png/jpg). When loading to listview, some of them I need to overlay with another transparent image. I do this using something like the following:

public Bitmap applyOverlay(Context context, Bitmap sourceImage, int overlayDrawableResourceId){
        Bitmap bitmap = null;
        try{
            int width = sourceImage.getWidth();
            int height = sourceImage.getHeight();
            Resources r = context.getResources();
            Drawable imageAsDrawable = new BitmapDrawable(r, sourceImage);
            Drawable[] layers = new Drawable[2];
            layers[0] = imageAsDrawable;
            layers[1] = new BitmapDrawable(r, BitmapUtils.decodeSampledBitmapFromResource(r, overlayDrawableResourceId, width, height));
            LayerDrawable layerDrawable = new LayerDrawable(layers);            
            bitmap = BitmapUtils.drawableToBitmap(layerDrawable);
        }catch (Exception ex){}
        return bitmap;
    }

where BitmapUtils is a custom class that implements bitmap-wise methods.

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.media.ThumbnailUtils;
import android.widget.ImageView;
import java.io.ByteArrayOutputStream;
import java.io.File;

public class BitmapUtils {

    public static Bitmap applyOverlay(Context context, Bitmap sourceImage, int overlayDrawableResourceId){
        Bitmap bitmap = null;
        try{
            int width = sourceImage.getWidth();
            int height = sourceImage.getHeight();
            Resources r = context.getResources();
            Drawable imageAsDrawable = new BitmapDrawable(r, sourceImage);
            Drawable[] layers = new Drawable[2];
            layers[0] = imageAsDrawable;
            layers[1] = new BitmapDrawable(r, BitmapUtils.decodeSampledBitmapFromResource(r, overlayDrawableResourceId, width, height));
            LayerDrawable layerDrawable = new LayerDrawable(layers);
            bitmap = BitmapUtils.drawableToBitmap(layerDrawable);
        }catch (Exception ex){}
        return bitmap;
    }

    public static Bitmap drawableToBitmap(Drawable drawable) {
        Bitmap bitmap = null;

        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            if(bitmapDrawable.getBitmap() != null) {
                return bitmapDrawable.getBitmap();
            }
        }

        if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
            bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
        } else {
            bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        return bitmap;
    }

    static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight){
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Compute inSampleSize
        options.inSampleSize = computeInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }
}



Using Universal Image Loader library for Android(UIL), this effect is achieved by writing a custom ImageDecoder and applying it to the ImageLoaderConfiguration.

The question is, how can I do this using Glide?
Thanks.

Mike Spike
  • 389
  • 8
  • 20

1 Answers1

7

The thing that worked for me:
I used the following answer: https://stackoverflow.com/a/33709650/3106975

public void display(final Context context, String mediaPath, final ImageView imageView, final boolean doApplyOverlay){
        try{                
                Glide.with(context)
                        .load(mediaPath)
                        .asBitmap()
                        .placeholder(R.drawable.placeholder_default)
                        .error(R.drawable.error_default)
                        .diskCacheStrategy(DiskCacheStrategy.ALL)
                        .into(new SimpleTarget<Bitmap>() {
                            @Override
                            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                                if (doApplyOverlay) {
                                    resource = BitmapUtils.applyOverlay(context, resource, R.drawable.overlay);
                                }
                                imageView.setImageBitmap(resource);
                            }
                        });    
        }catch (Exception ex){}
    }



So, to load a bitmap and to interact with it before displaying to the user, you need to implement a custom target and do the interactions there. SimpleTarget class provided by Glide implements the Target interface and allows that kind of things. For more information, you can visit Glide's CustomTargets wiki page on github: https://github.com/bumptech/glide/wiki/Custom-targets

Community
  • 1
  • 1
Mike Spike
  • 389
  • 8
  • 20