在实际开发中我们经常会对图片进行圆角处理,这里做一个小总结,文章结尾还有一个不到100行实现的,支持圆形,圆角和TransitionDrawable的ImageView
。
图片的圆角显示,从实现方法上讲分为两种做法:
- 在图片上做
- 在控件上做
从代码上讲,均使用 Android Graphics API:
- Xfermodes
- Regions
- Canvas.drawRoundRect
- Canvas.clipPath
- GradientDrawable.setCornerRadii
圆角和圆形的处理方式可以统一成一种,当圆角大小等于图片宽的一半时候,就变成了圆形。
原理
Clip + Region
- Region.Op.UNION:显示两层。
- Region.Op.XOR:去交集,显示两层。
- Region.Op.DIFFERENCE:去交集,显示下层。
- Region.Op.INTERSECT:取交集,显示上层。
Xfermodes
- PorterDuff.Mode.SRC_IN:取交集,显示上层。
- PorterDuff.Mode.DST_IN:取交集,显示下层。
示例
示例源码:https://github.com/gavinliu/BeautifulOfRoundedBitmap
在图片上做
把图片裁剪成圆角图片
优点:节约内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public Bitmap getRoundRectBitmap(Bitmap bitmap, int radius) { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); int bmWidth = bitmap.getWidth(); int bmHeight = bitmap.getHeight(); final RectF rectF = new RectF(0, 0, width, height); Canvas canvas = new Canvas(bitmap); paint.setXfermode(null); canvas.drawRoundRect(rectF, radius, radius, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rectF, paint); return bitmap; } |
在控件上做
ImageView控件绘制的时候,控制显示区域
优点:方便省事,适合各种图片框架
1 2 3 4 5 6 7 8 9 10 11 |
@Override protected void onDraw(Canvas canvas) { int saveCount = canvas.getSaveCount(); canvas.save(); super.onDraw(canvas); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); canvas.drawRoundRect(rectF, radius, radius, mPaint); canvas.restoreToCount(saveCount); } |
开源库:不到百行代码的圆角ImageView
面对网上各种CircleImageView,各种还可以自定义形状的ImageView,根本不知道选那个好,或许你就只想要一个能显示圆角的ImageView而已,网上的都太复杂,或者有使用限制,譬如说3K+ Star的CircleImageView不支持TransitionDrawable。
ShapedImageView
- 简洁,不到100行代码: ShapedImageView.java
- 支持
圆形
圆角矩形
- 支持
TransitionDrawable
dependencies
1
|
compile 'cn.gavinliu.android.lib:ShapedImageView:0.4'
|
attr
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ShapedImageView"> <attr name="shape_mode" format="enum"> <enum name="round_rect" value="1" /> <enum name="circle" value="2" /> </attr> <attr name="round_radius" format="dimension" /> </declare-styleable> </resources> |
Circle
1 2 3 4 5 6 |
<cn.gavinliu.android.lib.shapedimageview.ShapedImageView android:id="@+id/image1" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" app:shape_mode="circle" /> |
Round Rect
1 2 3 4 5 6 7 |
<cn.gavinliu.android.lib.shapedimageview.ShapedImageView android:id="@+id/image2" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" app:round_radius="20dp" app:shape_mode="round_rect" /> |