Android显示圆形图片的方法

相信大家在Android应用开发的时候经常会遇到需要使用圆形图片的时候,如果是我们程序中的图片还好说可以让我们的美工MM直接给我们做一个圆形的图片就搞定了。可是如果是从服务器上获取的或者是用户上传的呢我们该怎么办呢,比如用户的头像等。接下来我们就来看看在Android中怎样显示一个圆形的图片。

第一种方法:直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static Bitmap getRoundBitmap(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
//获得圆的直径
int d = Math.min(width, height);

Bitmap output = Bitmap.createBitmap(width,height, Config.ARGB_8888);
Canvas canvas = new Canvas(output);

//这里颜色随便填只要保证是不透明的就行也就是前两位是ff
int color = 0xff424242;
Paint paint = new Paint();
paint.setColor(color);
//设置抗锯齿
paint.setAntiAlias(true);

canvas.drawARGB(0, 0, 0, 0);
//先绘制一个圆
canvas.drawCircle(width/2, height/2, d/2, paint);

//设置两张图片相交的模式
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

canvas.drawBitmap(bitmap, 0, 0, paint);

return output;
}

主要代码就是通过canvas画一个圆,圆的直径就是图片的宽高最小的那一边,然后设置图片相交的模式,再将bitmap画上去取两张图片相交的部分就得到我们想要的圆了。最关键的代码就是 paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN))这一句,设置两张图片的叠加模式,具体有哪些模式呢,用一张图来表示:


通过图片相信大家很容易理解了,这里我们用的SrcIn根据上述图片就是取两张图片相交的部分。关于Xfermode的详细介绍请看这篇博文:http://blog.csdn.net/starfeng11/article/details/7000284介绍得很详细我这里就不做过多的介绍了。

接下来我们看另一种实现圆形图片显示的方法:

继承Imageview在ondraw里直接用canvas画出来。代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Path.FillType;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class RoundImageView extends ImageView {
private Paint paint;
private Path path;

public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

private void init() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

path = new Path();
path.setFillType(FillType.EVEN_ODD);

}

@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable != null) {

int w = this.getWidth();
int h = this.getHeight();

path.addRect(0, 0, w, h, Direction.CW);
path.addCircle(w / 2, h / 2, Math.min(w, h) / 2, Direction.CW);

canvas.saveLayerAlpha(0, 0, w, h, 255,
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
//图片只绘制这么大,相当于对图片进行缩放
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
canvas.drawPath(path, paint);

canvas.restore();
}
}

}

下面我们来分析一下关键代码:

1
2
//相信看了上面第一种办法和上面那张图对这个应该很了解了,设置paint的模式为clear清除,实际就是将要画的部分清除掉
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

1
2
//这段代码很关键,设置path中两个图形的叠加模式,类似于上面paint的Xfermode
path.setFillType(FillType.EVEN_ODD);

同样用一张图来说明:

通过图片相信大家很好理解,大家可以尝试一下,很神奇。

再看ondraw里面我们先在path里加了个矩形也就是图片的大小的矩形,然后又加了个圆形,因为我们设置path的FillType为EVEN_ODD所以实际我们drawpath出来的是矩形跟圆形相交之外的一个图形
222
黑色部分就是我们要画的部分。又因为我们paint设置Xfermode为Mode.CLEAR所以画的时候是把黑色的部分清除掉。但是实际上我们即使清除掉还是为黑色因为没有透明度所以我们用了下面的办法:

1
2
//创建一个具有透明度的图层,在调用canvas.restore()时会将该图层的内容绘制到canvas上。
canvas.saveLayerAlpha(0, 0, w, h, 255,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);

然后在图层上先画图片然后drawpath将黑色部分清除变成透明再调用canvas.restore()就大功告成了。
我们看一下效果图:
33

坚持原创技术分享,您的支持将鼓励我继续创作!