最近被问到如何将图片转为圆形显示出来,当时脑袋一蒙,想着图片加载框架(如glide等)不都有这个功能了么?但感觉自己确实没有特别关注这方面的内容,就去学习整理了一波,不说了,直接上代码:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;
import java.io.IOException;
/**
* 图片圆角化
*/
public class RoundImageView extends ImageView {
private Bitmap mBitmap;
private Paint mPaint;
public RoundImageView(Context context) {
this(context, null);
}
public RoundImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
//初始化画笔paint
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap == null || mBitmap.isRecycled()) {
try {
//直接网上找张图片,放到assets目录下
mBitmap = BitmapFactory.decodeStream(getContext().getAssets().open("avatar.jpeg"));
} catch (IOException e) {
e.printStackTrace();
}
}
//画出圆形图片就这三个方法
// shaderRound(canvas);
clipRound(canvas);
// xfermodRound(canvas);
}
/**
* 方式一:离屏混合模式实现
*/
private void xfermodRound(Canvas canvas) {
//新图层:离屏绘制,restore后才将内容显示到屏幕上
canvas.saveLayer(0, 0, getWidth(), getHeight(), mPaint);
//宽高自己指定,这里测试暂时用控件默认宽高
canvas.drawCircle(getWidth()/2, getHeight()/2, getHeight()/2, mPaint);
//设置混合模式为SRC_IN
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(mBitmap,null, new Rect(0, 0, getWidth(), getHeight()), mPaint);
canvas.restore();
}
/**
* 方式2:剪切路径实现,缺点是不能抗锯齿
*/
private void clipRound(Canvas canvas) {
canvas.save();
Path path = new Path();
path.addCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, Path.Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap(mBitmap, null, new Rect(0, 0, getWidth(), getHeight()), mPaint);
canvas.restore();
}
/**
* 方式三:shader实现,跟方式一无大的差别
*/
private void shaderRound(Canvas canvas) {
Matrix matrix = new Matrix();
float scaleX = getWidth() * 1f / mBitmap.getWidth();
float scaleY = getHeight() * 1f / mBitmap.getHeight();
matrix.setScale(scaleX, scaleY);
BitmapShader shader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
shader.setLocalMatrix(matrix);
mPaint.setShader(shader);
canvas.drawCircle(getWidth()/2f, getHeight()/2f, getHeight()/2, mPaint);
}
}