Android ImageLoader 显示圆角图片,可指定图片某几个角为圆角
来源:互联网 发布:centos关闭iptables 编辑:程序博客网 时间:2024/05/22 14:31
原文地址:http://blog.csdn.net/urmytch/article/details/52231419
Android中实现圆角图片的方式有很多种:
- 一、shape
- 二、.9图
- 三、XferMode
- 四、BitmapShader
- 五、ClipPath
其中一、二两种方法比较简单粗暴,三、四两种方法是比较常见的。
纵观目前主流的图片加载库:Picasso,Glide,Fresco,Android-Universal-Image-Loader等,它们都可以显示圆角的图片,但是除了Fresco可以指定哪几个角为圆角、哪几个角不为圆角外,其他三者都没有实现这个功能,而Fresco的侵入性比较强,布局中需使用com.facebook.drawee.view.simpledraweeview而不是简单的ImageView,同时Fresco需要在布局中每个角的圆角属性上设置false或true,这就未免有些麻烦了。
本文基于大众化图片加载库Universal-Image-Loader中的RoundedBitmapDisplayer源码进行拓展,自定义了一个FlexibleRoundedBitmapDisplayer,可以用简单快捷的代码指定图片的某几个角为圆角,某几个角不为圆角。
首先我们看一下Universal-Image-Loader中的RoundedBitmapDisplayer源代码:
public class RoundedBitmapDisplayer implements BitmapDisplayer { protected final int cornerRadius; protected final int margin; public RoundedBitmapDisplayer(int cornerRadiusPixels) { this(cornerRadiusPixels, 0); } public RoundedBitmapDisplayer(int cornerRadiusPixels, int marginPixels) { this.cornerRadius = cornerRadiusPixels; this.margin = marginPixels; } public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) { if(!(imageAware instanceof ImageViewAware)) { throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected."); } else { imageAware.setImageDrawable(new RoundedBitmapDisplayer.RoundedDrawable(bitmap, this.cornerRadius, this.margin)); } } public static class RoundedDrawable extends Drawable { protected final float cornerRadius; protected final int margin; protected final RectF mRect = new RectF(); protected final RectF mBitmapRect; protected final BitmapShader bitmapShader; protected final Paint paint; public RoundedDrawable(Bitmap bitmap, int cornerRadius, int margin) { this.cornerRadius = (float)cornerRadius; this.margin = margin; this.bitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); this.mBitmapRect = new RectF((float)margin, (float)margin, (float)(bitmap.getWidth() - margin), (float)(bitmap.getHeight() - margin)); this.paint = new Paint(); this.paint.setAntiAlias(true); this.paint.setShader(this.bitmapShader); this.paint.setFilterBitmap(true); this.paint.setDither(true); } protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); this.mRect.set((float)this.margin, (float)this.margin, (float)(bounds.width() - this.margin), (float)(bounds.height() - this.margin)); Matrix shaderMatrix = new Matrix(); shaderMatrix.setRectToRect(this.mBitmapRect, this.mRect, ScaleToFit.FILL); this.bitmapShader.setLocalMatrix(shaderMatrix); } public void draw(Canvas canvas) { canvas.drawRoundRect(this.mRect, this.cornerRadius, this.cornerRadius, this.paint); } public int getOpacity() { return -3; } public void setAlpha(int alpha) { this.paint.setAlpha(alpha); } public void setColorFilter(ColorFilter cf) { this.paint.setColorFilter(cf); } }}
可以看出Universal-Image-Loader显示圆角图片的方法属于上述第四种方法——BitmapShader,Shader被称之为着色器、渲染器,而BitmapShader产生的是一个图像,有点类似Photoshop中的图像渐变填充,它的作用就是通过Paint对画布进行指定Bitmap的填充,这里的填充模式是TileMode.CLAMP(拉伸模式,拉伸图片最后一像素点,一般指定图片合适大小时不会拉伸),也就是使用BitmapShader来进行图形填充。通俗些说就是用一张图片创建了一支具有图像填充功能的画笔,然后使用这个画笔画出一个形状,图片就在画出的地方显示。Universal-Image-Loader这里用drawRoundRect()方法画出了一个圆角矩形,故图像显示成了圆角矩形。
用过Photoshop的童鞋应该比较好理解,这就类似你给一个图层加了一个白蒙板,然后用不透明度100%的黑色画笔去在蒙板上绘制,画笔所过之处你原来的图层就会显现出来,就是这个意思。
那RoundedBitmapDisplayer画圆角图片的原理分析完了,说一下实现指定某几个角为圆角的思路:
思路就是先画一个圆角矩形把这个图片变成圆角,然后你想让那个角不是圆角,就把对应角位置那部分的原图画出来即可,画一个矩形就可以把原来的角显示出来,用的方法是drawRect()。
下面就是FlexibleRoundedBitmapDisplayer的完整代码:
/** * Universal-Image-Loader中RoundedBitmapDisplayer的增强版,可以自定义图片4个角中的指定角为圆角<br> */public class FlexibleRoundedBitmapDisplayer implements BitmapDisplayer { protected int cornerRadius; protected int corners; public static final int CORNER_TOP_LEFT = 1; public static final int CORNER_TOP_RIGHT = 1 << 1; public static final int CORNER_BOTTOM_LEFT = 1 << 2; public static final int CORNER_BOTTOM_RIGHT = 1 << 3; public static final int CORNER_ALL = CORNER_TOP_LEFT | CORNER_TOP_RIGHT | CORNER_BOTTOM_LEFT | CORNER_BOTTOM_RIGHT; /** * 构造方法说明:设定圆角像素大小,所有角都为圆角 * @param cornerRadiusPixels 圆角像素大小 */ public FlexibleRoundedBitmapDisplayer(int cornerRadiusPixels){ this.cornerRadius = cornerRadiusPixels; this.corners = CORNER_ALL; } /** * 构造方法说明:设定圆角像素大小,指定角为圆角 * @param cornerRadiusPixels 圆角像素大小 * @param corners 自定义圆角<br> * CORNER_NONE 无圆角<br> * CORNER_ALL 全为圆角<br> * CORNER_TOP_LEFT | CORNER_TOP_RIGHT | CORNER_BOTTOM_LEFT | CORNER_BOTTOM_RIGHT 指定圆角(选其中若干组合 ) <br> */ public FlexibleRoundedBitmapDisplayer(int cornerRadiusPixels, int corners){ this.cornerRadius = cornerRadiusPixels; this.corners = corners; } @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 FlexibleRoundedDrawable(bitmap,cornerRadius,corners)); } public static class FlexibleRoundedDrawable extends Drawable { protected final float cornerRadius; protected final RectF mRect = new RectF(), mBitmapRect; protected final BitmapShader bitmapShader; protected final Paint paint; private int corners; public FlexibleRoundedDrawable(Bitmap bitmap, int cornerRadius, int corners) { this.cornerRadius = cornerRadius; this.corners = corners; 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); } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mRect.set(0, 0, bounds.width(), bounds.height()); Matrix shaderMatrix = new Matrix(); shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL); bitmapShader.setLocalMatrix(shaderMatrix); } @Override public void draw(Canvas canvas) { //先画一个圆角矩形将图片显示为圆角 canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint); int notRoundedCorners = corners ^ CORNER_ALL; //哪个角不是圆角我再把你用矩形画出来 if ((notRoundedCorners & CORNER_TOP_LEFT) != 0) { canvas.drawRect(0, 0, cornerRadius, cornerRadius, paint); } if ((notRoundedCorners & CORNER_TOP_RIGHT) != 0) { canvas.drawRect(mRect.right - cornerRadius, 0, mRect.right, cornerRadius, paint); } if ((notRoundedCorners & CORNER_BOTTOM_LEFT) != 0) { canvas.drawRect(0, mRect.bottom - cornerRadius, cornerRadius, mRect.bottom, paint); } if ((notRoundedCorners & CORNER_BOTTOM_RIGHT) != 0) { canvas.drawRect(mRect.right - cornerRadius, mRect.bottom - cornerRadius, mRect.right, mRect.bottom, paint); } } @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); } }}
然后就可以这样使用Universal-Image-Loader了:
/* * 设置图片---自定义图片4个角中的指定角为圆角 * @param url 图片的url * @param cornerRadius 圆角像素大小 * @param corners 自定义圆角:<br> * 以下参数为FlexibleRoundedBitmapDisplayer中静态变量:<br> * CORNER_NONE 无圆角<br> * CORNER_ALL 全为圆角<br> * CORNER_TOP_LEFT | CORNER_TOP_RIGHT | CORNER_BOTTOM_LEFT | CORNER_BOTTOM_RIGHT 指定圆角(选其中若干组合 ) <br> * @param image url为空时加载该图片 * @param imageView 要设置图片的ImageView */ public void setRoundedImage(String url, int cornerRadius, int corners, int image, ImageView imageView) { ImageLoader imageLoader = ImageLoader.getInstance(); DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(image).showStubImage(image) .showImageForEmptyUri(image)//url为空时显示的图片 .showImageOnFail(image)//加载失败显示的图片 .cacheInMemory()//内存缓存 .cacheOnDisc()//磁盘缓存 .displayer(new FlexibleRoundedBitmapDisplayer(cornerRadius,corners)) // 自定义增强型BitmapDisplayer .build(); imageLoader.displayImage(url, imageView, options); }
来个示例:
看看效果:
- Android ImageLoader 显示圆角图片,可指定图片某几个角为圆角
- Android显示圆角图片,可指定图片某几个角为圆角
- Android显示圆角图片,可指定图片某几个角为圆角
- Android显示圆角图片,可指定图片某几个角为圆角
- android使用ImageLoader显示圆角图片
- android 显示圆角图片,可指定哪个角为圆角
- Imageloader 使用指南之 显示圆角图片
- 使用ImageLoader显示圆角图片、圆形图片、加载drawable的BUG
- Android 显示图片圆角
- 关于ImageLoader 设置圆角参数后不显示图片的问题
- 用ImageLoader加载圆角图片(不是圆形)
- 初学Android之viewPager+imageLoader+图片圆角(类似qq头像)+xListView+DrawLayout
- 圆角图片显示
- 显示圆角图片
- 圆角图片显示
- 图片显示圆角
- android设置图片为圆角
- 【Android】将图片转换为圆角
- HDU---6029 Graph Theory 【二分图匹配思想相关运用】
- MyBatis学习总结(五)——实现关联表查询
- [LeetCode]594.Longest Harmonious Subsequence
- Elsevier上发表论文的若干要求
- 分布式系统可用性与一致性
- Android ImageLoader 显示圆角图片,可指定图片某几个角为圆角
- QT5.4.0环境下配置OpenGL的glut库
- 嵌入式实时操作系统μC/OS-Ⅱ 在DSP芯片上的移植与测试
- 网络配置的四大基本要素: IP + Netmask + Gateway + DNS
- Android百大框架学习计划和状况
- Docker镜像简介
- ES6入门学习
- HDU --- 1878 【欧拉回路】
- webdriver+ant+jenkins自动化测试实践