利用Canvas绘制圆形图
最近实现一个业务需求,要求将用户头像、用户名和正文内容合成为一张图片,以作为给微信小程序分享的封面图。通过一些ImageView控件是很容易实现圆形头像的,但这里需要创建一块画布,在Canvas上画出圆形头像,如果细节处理不好,可能达不到理想的效果。
通常用Java代码绘制圆形图有三种方法,分别是使用BitmapShader、PorterDuffXfermode和ClipPath。这里记录一下这三种画圆形图的代码实现:
BitmapShager 图片渲染方式
public Bitmap getCirleBitmap(Bitmap bmp) {
//获取bmp的宽高 小的一个做为圆的直径r
int w = bmp.getWidth();
int h = bmp.getHeight();
int r = Math.min(w, h);
//创建一个paint
Paint paint = new Paint();
paint.setAntiAlias(true);
//新创建一个Bitmap对象newBitmap 宽高都是r
Bitmap newBitmap = Bitmap.createBitmap(r, r, Bitmap.Config.ARGB_8888);
//创建一个使用newBitmap的Canvas对象
Canvas canvas = new Canvas(newBitmap);
//创建一个BitmapShader对象 使用传递过来的原Bitmap对象bmp
BitmapShader bitmapShader = new BitmapShader(bmp, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
//paint设置shader
paint.setShader(bitmapShader);
//canvas画一个圆 使用设置了shader的paint
canvas.drawCircle(r / 2, r / 2, r / 2, paint);
return newBitmap;
}
PorterDuffXfermode 图片混合模式
public Bitmap getCirleBitmap(Bitmap bmp) {
//获取bmp的宽高 小的一个做为圆的直径r
int w = bmp.getWidth();
int h = bmp.getHeight();
int r = Math.min(w, h);
//创建一个paint
Paint paint = new Paint();
paint.setAntiAlias(true);
//新创建一个Bitmap对象newBitmap 宽高都是r
Bitmap newBitmap = Bitmap.createBitmap(r, r, Bitmap.Config.ARGB_8888);
//创建一个使用newBitmap的Canvas对象
Canvas canvas = new Canvas(newBitmap);
//canvas画一个圆形
canvas.drawCircle(r / 2, r / 2, r / 2, paint);
//然后 paint要设置Xfermode 模式为SRC_IN 显示上层图像(后绘制的一个)的相交部分
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//canvas调用drawBitmap直接将bmp对象画在画布上
//因为paint设置了Xfermode,所以最终只会显示这个bmp的一部分
//也就是bmp的和下层圆形相交的一部分圆形的内容
canvas.drawBitmap(bmp, 0, 0, paint);
return newBitmap;
}
ClipPath 裁剪区域
public Bitmap getCirleBitmap(Bitmap bmp) {
//获取bmp的宽高 小的一个做为圆的直径r
int w = bmp.getWidth();
int h = bmp.getHeight();
int r = Math.min(w, h);
//创建一个paint
Paint paint = new Paint();
paint.setAntiAlias(true);
//新创建一个Bitmap对象newBitmap 宽高都是r
Bitmap newBitmap = Bitmap.createBitmap(r, r, Bitmap.Config.ARGB_8888);
//创建一个使用newBitmap的Canvas对象
Canvas canvas = new Canvas(newBitmap);
//创建一个Path对象,path添加一个圆 圆心半径均是r / 2, Path.Direction.CW顺时针方向
Path path = new Path();
path.addCircle(r / 2, r / 2, r / 2, Path.Direction.CW);
//canvas绘制裁剪区域
canvas.clipPath(path);
//canvas将图画到留下的圆形区域上
canvas.drawBitmap(bmp, 0, 0, paint);
return newBitmap;
}