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 类形参数。

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); }
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 重复方式不一样,他是以镜像方式平铺。
处理成黑白 代码如下:
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)