安卓Glide加载图片文件并应用叠加效果,然后设置到ImageView中。

4

我有一些图片文件(png/jpg),当加载到列表视图时,有些需要与另一个透明图片叠加。我使用以下类似的方法来实现:

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;
    }

BitmapUtils是一个自定义类,实现了位图处理方法。

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);
    }
}

使用Universal Image Loader library for Android(简称UIL),通过编写自定义的ImageDecoder并将其应用于ImageLoaderConfiguration可以实现此效果。但问题是,如何使用Glide实现此效果?谢谢。
1个回答

7
我成功的方法是:
我使用了以下答案:https://dev59.com/jZHea4cB1Zd3GeqPkRbk#33709650

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){}
    }



因此,若要在显示给用户之前加载位图并与其交互,您需要实现一个自定义目标并在那里进行交互。Glide提供的SimpleTarget类实现了Target接口,并允许这种操作。有关更多信息,请访问Glide在github上的CustomTargets wiki页面:https://github.com/bumptech/glide/wiki/Custom-targets


我在哪里可以找到BitmapUtils类? - AndroidRuntimeException
@AgustinSivoplás 这不是一个库类,我专门为这个项目创建了它来保存基本的位图方法。 - Mike Spike
1
我创建了一个公共Gist,如果将来有人需要BitmapUtils.java类,可以使用它。https://gist.github.com/agustinsivoplas/44f01672d698394dc28edda2c7a05cb6 - AndroidRuntimeException
@MikeSpike,你能一并贴出与BitmapUtils.applyOverlay相关的代码吗? - Sreehari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接