Android 绘制圆角图片的几种方式:
一.使用PorterDuffXfermode
PorterDuffXfermode : 是设置两个图层交集区域的显示方式,所以我们可以这样想:一个圆与一个图片的共同
区域,我们让它显示出来,OK ! 使用如下代码:
public static Bitmap CirCreateBitmap(Context context,int test) {
Bitmap mBitmap = BitmapFactory.decodeResource(context.getResources(), test);
Bitmap mOut = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mOut);
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
float realX = Math.min(mBitmap.getWidth() / 2, mBitmap.getHeight() / 2); // 比较宽和高 谁小用谁
canvas.drawCircle(mBitmap.getWidth() / 2, mBitmap.getHeight() / 2, realX, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); // 核心方法
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
return mOut;
}
传入
图片的ID 返回一个圆形Bitmap ,这里只给出这一种方法,其他重载可自行尝试。
二.使用Shader
shader 又被称为着色器, 渲染器,它用来实现一系列渐变,渲染效果。
package wang.li.com.drawcirclebitmap.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* 作者 : Long Create: 2016/9/28 14:28
* <p/>
* 其实渲染的是画笔, 先要什么图形,画出来就好了
*/
public class CircleBitmapShader extends ImageView {
public CircleBitmapShader(Context context) {
this(context, null);
}
public CircleBitmapShader(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleBitmapShader(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
}
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas); // 要注释掉,不然会覆盖圆行图片
BitmapDrawable bdb = (BitmapDrawable) getDrawable();
if (bdb == null) {
return;
}
Bitmap bitmap = bdb.getBitmap();
// Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test); // 这种方式是直接写死
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(bitmapShader);
float realX = Math.min(bitmap.getWidth() / 2, bitmap.getHeight() / 2); // 比较宽和高 谁小用谁
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, realX, paint);
}
}
这里提供了 一个圆形的ImagerView ,可以在布局中直接使用。 当然Shader 还有其他功能,这里直接少绘制
圆形图片。有兴趣可以查阅相关资料 。
三. 通过Drawable来实现,其实也是渲染:
package wang.li.com.drawcirclebitmap.view;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
/**
* 作者 : Long Create: 2016/9/28 14:56
*
*
* 有两个构造方法 分别是 1. 画圆角矩形图片
* 2. 是否绘制圆形图片
*
* 当然和在一起也行 不过看着不爽!
*/
public class CirDrawable extends Drawable {
private Paint mPaint;
private Bitmap mBitmap;
private RectF rectF;
private int mRadiusX ;
private int mRadiusY ;
private boolean isCircle = false ;
/**
* 构造方法 绘制带圆周角的方形图片
* @param bitmap
* @param radiusX x轴方向的半径
* @param radiusY y轴方向的半径
*/
public CirDrawable(Bitmap bitmap,int radiusX ,int radiusY) {
this.mBitmap = bitmap;
this.mRadiusX = radiusX ;
this.mRadiusY = radiusY ;
this.isCircle = false ;
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(bitmapShader);
}
/**
* 构造方法
* @param bitmap
* @param isCircle true 是圆形图片 false 不是圆形图片
*/
public CirDrawable(Bitmap bitmap,boolean isCircle) {
this.mBitmap = bitmap;
this.mRadiusX = 0 ;
this.mRadiusY = 0 ;
this.isCircle = isCircle ;
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(bitmapShader);
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
rectF = new RectF(left, top, right, bottom);
}
@Override
public void draw(Canvas canvas) {
if (isCircle){
float realX= Math.min(mBitmap.getWidth() / 2 , mBitmap.getHeight() / 2 ) ; // 比较宽和高 谁小用谁
canvas.drawCircle(mBitmap.getWidth() / 2, mBitmap.getHeight() / 2, realX, mPaint);
}else{
canvas.drawRoundRect(rectF, mRadiusX, mRadiusY, mPaint);
}
}
@Override
public int getIntrinsicWidth() {
return mBitmap.getWidth();
}
@Override
public int getIntrinsicHeight() {
return mBitmap.getHeight();
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
好了 , 暂时就介绍到这。
在具体使用中,要根据具体情况,看看选择哪一个,最好自己在优化一下,根据具体情况具体对待!