本文和大家分享的主要是
android
中实现圆角图片的几种方法,一起来看看吧,希望对大家
学习
android
有所帮助。
方法一:
setXfermode
法
此种方式就是再
new
一个相同尺寸的
bitmap
,然后使用
paint.setXfermode(newPorterDuffXfermode(Mode.SRC_IN));
先画圆角矩形,再画原始
bitmap
,然后就得到了一个圆角的
bitmap
了。
public
static
Bitmap
getRoundedCornerBitmap
(Bitmap bitmap,
float
roundPx){
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas =
new
Canvas(output);
final
int
color= 0xff424242;
final
Paintpaint =
new
Paint();
final
Rectrect =
new
Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());
final
RectFrectF =
new
RectF(rect);
paint.setAntiAlias(
true
);
canvas.drawARGB(0, 0,0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF,roundPx, roundPx, paint);
paint.setXfermode(
new
PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap,rect, rect, paint);
return
output;
}
点评:
早期用得较多,占用
bitmap
双倍内存。
方法二:使用
BitmapShader
此种方式是先将
bitmap
生成
BitmapShader
,然后将其绘制到
canvas
中
,
部分关键代码如下,完整代码请参考
QuickAF
中的
RoundImageView
bitmapShader = new BitmapShader(bitmap,Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(bitmapShader);
@Override
public
void
draw
(Canvascanvas) {
Rect bounds = getBounds();
canvas.drawRoundRect(fillRect,radius, radius, paint);
if
(mBorderWidth> 0) {
if
(mIsCircle){
canvas.drawCircle(bounds.width()/ 2, bounds.height() / 2, radius, strokePaint);
}
else
{
canvas.drawRoundRect(fillRect,radius, radius, strokePaint);
}
}
}
点评:
占用内存较大,实现有点小复杂。
方法三:图片加载库
目前
github
上有许多流行的图片加载库,基于上都附带圆角图片功能,只需要稍微配置一下,即可轻松的实现想要的效果。其实在底层,无非也是使用上面的两种方式。比如
Android-Universal-Image-Loader
早期的
RoundedBitmapDisplayer
使用
setXfermode
来实现,后来使用
BitmapShader
实现。
DisplayImageOptions
options
=
new
DisplayImageOptions.Builder()
.displayer(
new
RoundedBitmapDisplayer())// display rounded bitmap
.build();
再以比较另类的
fresco
为例,虽然底层是以
C
实现,不过在圆角处理上,仍然还是在
Java
层实现,用的方式还是
BitmapShader
。不过对于非
bitmap
的圆角实现,
fresco
是用
Paint
直接画的。附上
fresco
配置。
android:id="@+id/my_image_view"
android:layout_width="20dp"
android:layout_height="20dp"
fresco:fadeDuration="300"
fresco:actualImageScaleType="focusCrop"
fresco:placeholderImage="@color/wait_color"
fresco:placeholderImageScaleType="fitCenter"
fresco:failureImage="@drawable/error"
fresco:failureImageScaleType="centerInside"
fresco:retryImage="@drawable/retrying"
fresco:retryImageScaleType="centerCrop"
fresco:progressBarImage="@drawable/progress_bar"
fresco:progressBarImageScaleType="centerInside"
fresco:progressBarAutoRotateInterval="1000"
fresco:backgroundImage="@color/blue"
fresco:overlayImage="@drawable/watermark"
fresco:pressedStateOverlayImage="@color/red"
fresco:roundAsCircle="false"
fresco:roundedCornerRadius="1dp"
fresco:roundTopLeft="true"
fresco:roundTopRight="false"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="true"
fresco:roundWithOverlayColor="@color/corner_color"
fresco:roundingBorderWidth="2dp"
fresco:roundingBorderColor="@color/border_color"
/>
点评:
由框架实现,使用简单,稳定。
方法四:遮罩
此种方式还是使用
setXfermode
,不过与方法一不同的是:不对图片作任何更改,只在圆角之外再画一层与背景颜色相同的四个角来遮挡,在视觉上造成圆角图片的效果。关键代码如下:
@Override
protected
void
onDraw
(Canvascanvas) {
super
.onDraw(canvas);
if
(src!=
null
&& dst !=
null
){
int
w= getMeasuredWidth(), h = getMeasuredHeight();
int
sc= canvas.saveLayer(0, 0, w, h,
null
,
Canvas.MATRIX_SAVE_FLAG| Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
| Canvas.FULL_COLOR_LAYER_SAVE_FLAG| Canvas.CLIP_TO_LAYER_SAVE_FLAG);
canvas.drawBitmap(dst,0, 0, paint); //
圆角矩形
paint.setXfermode(mode);// new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);
canvas.drawBitmap(src,0, 0, paint); //
长方形
paint.setXfermode(
null
);
canvas.restoreToCount(sc);
}
}
使用这种方式,圆角化的对象不限于
ImageView
,还可以是任意的
layout
哦,比如下面的示例
<
FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<
LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<
ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:src="@color/colorAccent"/>
<
TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/black_alpha_50"
android:padding="12dp"
android:text="Iam text"/>
LinearLayout>
<
cn.ieclipse.af.view.RoundMaskView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:radius="10dp"
app:af_borderColor="@color/white"
app:af_borderWidth="1dp"/>FrameLayout>
配合
FrameLayout
,将
LinearLayout
实现了圆角,在视觉效果上,
ImageView
左上和右上圆角,
TextView
左下和右下圆角。
点评:
具有一定的局限性,不过不限于图片,所有的
Layout
都可以在视觉上实现圆角。
来源:简书
赞 | 0