ImageLoader源码解析(四) 补充 Displayer的实现
来源:互联网 发布:网络摄像头如何修改ip 编辑:程序博客网 时间:2024/06/05 20:54
ImageLoader源码解析(四) 补充 Displayer的实现
1 前言
一般来说,如果说到原型图片,或者边框,或者特别形状的图片处理,那么我们可能第一个想到的是 自定义ImageView去处理,在draw方法里写我们的逻辑
这篇文章说一下除了自定义ImageView的另外一种处理,那就是自定义一个Drawable,
这就是ImageLoader中提供的displayer的对于图片转换的解决方案
2 基础知识
- Drawable
- paint
- BitmapShader
- Bitmap
- Matrix
- 自定义View涉及到的Pain,Rect,Canvas等,如果对自定义View不了解,建议去看下自定义View,主要是绘制那块的处理,其实自定义Drawable和自定义View真的很像
3 解析
Imageloader中提供的有很多,最常用的,就是圆形,弧形的处理了,我们来看这两个是怎么写的
3.1 CircleBitmapDisplayer圆形Drawable
public class CircleBitmapDisplayer implements BitmapDisplayer { /** * 边框的颜色 */ protected final Integer strokeColor; /** * 边框宽度 */ protected final float strokeWidth; public CircleBitmapDisplayer() { this(null); } public CircleBitmapDisplayer(Integer strokeColor) { this(strokeColor, 0); } public CircleBitmapDisplayer(Integer strokeColor, float strokeWidth) { this.strokeColor = strokeColor; this.strokeWidth = strokeWidth; } @Override public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) { if (!(imageAware instanceof ImageViewAware)) { throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected."); } imageAware.setImageDrawable(new CircleDrawable(bitmap, strokeColor, strokeWidth)); } public static class CircleDrawable extends Drawable { /** * 弧度 */ protected float radius; /** * 绘制范围 */ protected final RectF mRect = new RectF(); /** * bitmap范围 */ protected final RectF mBitmapRect; protected final BitmapShader bitmapShader; /** * 图形画笔 */ protected final Paint paint; /** * 边框画笔 */ protected final Paint strokePaint; /** * 边框宽度 */ protected final float strokeWidth; /** * 边框的弧度 */ protected float strokeRadius; public CircleDrawable(Bitmap bitmap, Integer strokeColor, float strokeWidth) { radius = Math.min(bitmap.getWidth(), bitmap.getHeight()) / 2; bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapRect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); paint = new Paint(); //设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。但是效果更好 paint.setAntiAlias(true); paint.setShader(bitmapShader); //如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示速度 paint.setFilterBitmap(true); //设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰 paint.setDither(true); //如果边框颜色设置了,那么就有边框 if (strokeColor == null) { strokePaint = null; } else { strokePaint = new Paint(); strokePaint.setStyle(Paint.Style.STROKE); strokePaint.setColor(strokeColor); strokePaint.setStrokeWidth(strokeWidth); strokePaint.setAntiAlias(true); } this.strokeWidth = strokeWidth; strokeRadius = radius - strokeWidth / 2; } /** * 范围发生变化时,可能如果imagview大小发生变化,这里会调用吧 * * @param bounds */ @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mRect.set(0, 0, bounds.width(), bounds.height()); radius = Math.min(bounds.width(), bounds.height()) / 2; strokeRadius = radius - strokeWidth / 2; //重新设置bitmap的大小去适应新的绘制范围,这里其实就是fitxy处理 Matrix shaderMatrix = new Matrix(); /** * 设置变换规则,自动计算mBitmapRect->mRect变换的规则<br/> * 第三个参数,有FILL,start,end,center,还记得,ImageView的ScaleType吗,对比理解<br/> * Fill就是FitXY */ shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL); //为bitmapshader设置变换矩阵 bitmapShader.setLocalMatrix(shaderMatrix); } @Override public void draw(Canvas canvas) { //绘制bitmap canvas.drawCircle(radius, radius, radius, paint); if (strokePaint != null) { //绘制边框 canvas.drawCircle(radius, radius, strokeRadius, strokePaint); } } //-------------------------下面是通过设置画笔,然后重绘,来支持View的一些设置(透明度,颜色过滤,也可以添加其他的属性支持)------------------------------- /** * 获取透明度的格式,看一下父类中的注释 * {@link Drawable#getOpacity() } * <p> * 只有四个返回值 * {@link android.graphics.PixelFormat}: * {@linkplain android.graphics.PixelFormat#UNKNOWN 未知}, * {@linkplain android.graphics.PixelFormat#TRANSLUCENT 系统选择支持半透明的格式 bits}, * {@linkplain android.graphics.PixelFormat#TRANSPARENT 系统选择支持透明度的格式 0-1 }, or * {@linkplain android.graphics.PixelFormat#OPAQUE 系统选择不透明格式(不需要alpha位)}. * * @return */ @Override public int getOpacity() { //系统选择支持半透明的格式 return PixelFormat.TRANSLUCENT; } @Override public void setAlpha(int alpha) { paint.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter cf) { paint.setColorFilter(cf); } }}
注释很详细了,其实自定义Drawable,很像自定义一个View,我没有看过View的源码,现在让我怀疑View中其实操控的也是绘制一个Drawable,然后将Drawable显示到View中
3.2 RoundedBitmapDisplayer 弧形图像绘制
@Override public void draw(Canvas canvas) { //貌似唯一有变化的就是这里了吧,DrawCircle变成了Round canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint); }
4 参考
Android 自定义Drawable
http://www.cnblogs.com/a284628487/p/5204170.html
http://blog.csdn.net/lmj623565791/article/details/43752383
Matrix:
http://blog.csdn.net/flash129/article/details/8234599
5 解析源码
https://github.com/yizeliang/Android-Universal-Image-Loader
阅读全文
0 0
- ImageLoader源码解析(四) 补充 Displayer的实现
- ImageLoader displayer显示....
- ImageLoader源码解析-----ImageLoader的结构
- ImageLoader源码解析(五) 补充 针对ListView或者RecycleView的优化
- ImageLoader源码解析(二) 缓存实现
- Universal-ImageLoader源码解析
- ImageLoader源码解析
- ImageLoader 源码解析
- ImageLoader源码解析(一)
- ImageLoader使用及源码解析
- ImageLoader中自定义Displayer来展示任意圆角
- Android-Universal-Imageloader源码完全解析
- ImageLoader源码解析(三) 线程调度
- 实现简单的ImageLoader
- imageLoader的轻量级实现
- ImageLoader的实现
- 实现简单的ImageLoader
- 《Android源码设计模式解析与实战》一、ImageLoader图片加载的设计
- K:(1)算法时间复杂度的简介
- TYPEERROR: UNDEFINED IS NOT A FUNCTION解决方法
- Tomcat使用JKS格式证书配置HTTPS
- Android Activity Launch Mode
- 冒泡排序做排行榜,用的是NGUI里的Label
- ImageLoader源码解析(四) 补充 Displayer的实现
- 考虑用静态工厂方法代替构造器
- 【AJAX】无法启动GlassFish Server
- 搜狐笔试之Kolakoski序列
- Unreal Engine 4 中的 UI 优化技巧
- Python2.7版本和3.6版本兼容问题
- HDU
- C#206课的主要内容
- 响应式 Web 设计 -- HTML5 和 CSS3 实践指南