android 加载图片圆角等功能的处理

android 加载图片圆角等功能的处理

 

以Glide为例:

Glide.with(getContext()).load(item.getSoftLogo()).transform(this.glideRoundTransform).into(vh.ivSoftIcon);

 

Glide 提供了transform()方法。

 

   /**
     * Transform {@link GlideDrawable}s using the given
     * {@link com.bumptech.glide.load.resource.bitmap.BitmapTransformation}s.
     *
     * <p>
     *     Note - Bitmap transformations will apply individually to each frame of animated GIF images and also to
     *     individual {@link Bitmap}s.
     * </p>
     *
     * @see #centerCrop()
     * @see #fitCenter()
     * @see #bitmapTransform(com.bumptech.glide.load.Transformation[])
     * @see #transform(com.bumptech.glide.load.Transformation[])
     *
     * @param transformations The transformations to apply in order.
     * @return This request builder.
     */
    public DrawableRequestBuilder<ModelType> transform(BitmapTransformation... transformations) {
        return bitmapTransform(transformations);
    }

此方法接受 BitmapTransformation 类形参数。

android 加载图片圆角等功能的处理android 加载图片圆角等功能的处理
import android.content.Context;
import android.graphics.Bitmap;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.util.Util;

/**
 * A simple {@link com.bumptech.glide.load.Transformation} for transforming {@link android.graphics.Bitmap}s that
 * abstracts away dealing with {@link com.bumptech.glide.load.engine.Resource} objects for subclasses.
 *
 * Use cases will look something like this:
 * <pre>
 * <code>
 * public class FillSpace extends BaseBitmapTransformation {
 *     {@literal @Override}
 *     public Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
 *         if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) {
 *             return toTransform;
 *         }
 *
 *         return Bitmap.createScaledBitmap(toTransform, outWidth, outHeight, true);
 *     }
 * }
 * </code>
 * </pre>
 */
public abstract class BitmapTransformation implements Transformation<Bitmap> {

    private BitmapPool bitmapPool;

    public BitmapTransformation(Context context) {
        this(Glide.get(context).getBitmapPool());
    }

    public BitmapTransformation(BitmapPool bitmapPool) {
        this.bitmapPool = bitmapPool;
    }

    @Override
    public final Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
        if (!Util.isValidDimensions(outWidth, outHeight)) {
            throw new IllegalArgumentException("Cannot apply transformation on width: " + outWidth + " or height: "
                    + outHeight + " less than or equal to zero and not Target.SIZE_ORIGINAL");
        }
        Bitmap toTransform = resource.get();
        int targetWidth = outWidth == Target.SIZE_ORIGINAL ? toTransform.getWidth() : outWidth;
        int targetHeight = outHeight == Target.SIZE_ORIGINAL ? toTransform.getHeight() : outHeight;
        Bitmap transformed = transform(bitmapPool, toTransform, targetWidth, targetHeight);

        final Resource<Bitmap> result;
        if (toTransform.equals(transformed)) {
            result = resource;
        } else {
            result = BitmapResource.obtain(transformed, bitmapPool);
        }

        return result;
    }

    /**
     * Transforms the given {@link android.graphics.Bitmap} based on the given dimensions and returns the transformed
     * result.
     *
     * <p>
     *   The provided Bitmap, toTransform, should not be recycled or returned to the pool. Glide will automatically
     *   recycle and/or reuse toTransform if the transformation returns a different Bitmap. Similarly implementations
     *   should never recycle or return Bitmaps that are returned as the result of this method. Recycling or returning
     *   the provided and/or the returned Bitmap to the pool will lead to a variety of runtime exceptions and drawing
     *   errors. See #408 for an example. If the implementation obtains and discards intermediate Bitmaps, they may
     *   safely be returned to the BitmapPool and/or recycled.
     * </p>
     *
     * <p>
     *     outWidth and outHeight will never be {@link com.bumptech.glide.request.target.Target#SIZE_ORIGINAL}, this
     *     class converts them to be the size of the Bitmap we're going to transform before calling this method.
     * </p>
     *
     * @param pool A {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} that can be used to obtain and
     *             return intermediate {@link Bitmap}s used in this transformation. For every
     *             {@link android.graphics.Bitmap} obtained from the pool during this transformation, a
     *             {@link android.graphics.Bitmap} must also be returned.
     * @param toTransform The {@link android.graphics.Bitmap} to transform.
     * @param outWidth The ideal width of the transformed bitmap (the transformed width does not need to match exactly).
     * @param outHeight The ideal height of the transformed bitmap (the transformed heightdoes not need to match
     *                  exactly).
     */
    protected abstract Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight);
}
View Code

BitmapTransformation 虚拟方法

protected abstract Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight);

意思通过此方法转换和处理图片,并返回给Glide一个bitmap.此bitmap Glide也将替你管理。
剩下的只要你去做处理了。


下面做一个图角的处理
通过重写paint绘制叠加的效果来处理。
关键代码如下:
 /**
     * @param pool 
     * @param source 
     * @return 
     */
    private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        //获取一张位图用来往上面绘制
        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        }

        //使用获取的位图新建一张画布
        Canvas canvas = new Canvas(result);
        //新建一个画笔
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        //先画图片,再画圆角矩形,获取交集
        return result;
    }
BitmapShader 
public   BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)
调用这个方法来产生一个画有一个位图的渲染器(Shader)。
bitmap   在渲染器内使用的位图
tileX      The tiling mode for x to draw the bitmap in.   在位图上X方向花砖模式
tileY     The tiling mode for y to draw the bitmap in.    在位图上Y方向花砖模式
TileMode:(一共有三种)
CLAMP  :如果渲染器超出原始边界范围,会复制范围内边缘染色。
REPEAT :横向和纵向的重复渲染器图片,平铺。
MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT 重复方式不一样,他是以镜像方式平铺。

android 加载图片圆角等功能的处理

处理成黑白 代码如下:

 1    int w = source.getWidth();
 2         int h = source.getHeight();
 3 
 4         Bitmap resultBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
 5         int color = 0;
 6         int a,r,g,b,r1,g1,b1;
 7         int[] oldPx = new int[w * h];
 8         int[] newPx = new int[w * h];
 9 
10         source.getPixels(oldPx, 0, w, 0, 0, w, h);
11         for(int i = 0; i < w * h; i++){
12             color = oldPx[i];
13 
14             r = Color.red(color);
15             g = Color.green(color);
16             b = Color.blue(color);
17             a = Color.alpha(color);
18 
19             //黑白矩阵
20             r1 = (int) (0.33 * r + 0.59 * g + 0.11 * b);
21             g1 = (int) (0.33 * r + 0.59 * g + 0.11 * b);
22             b1 = (int) (0.33 * r + 0.59 * g + 0.11 * b);
23 
24             //检查各像素值是否超出范围
25             if(r1 > 255){
26                 r1 = 255;
27             }
28 
29             if(g1 > 255){
30                 g1 = 255;
31             }
32 
33             if(b1 > 255){
34                 b1 = 255;
35             }
36 
37             newPx[i] = Color.argb(a, r1, g1, b1);
38         }
39         resultBitmap.setPixels(newPx, 0, w, 0, 0, w, h);
40         return resultBitmap;

 效果如下:

android 加载图片圆角等功能的处理

 

同理可以加其它滤镜、水印等。