Android种图片圆形化的三种方式

最近被问到如何将图片转为圆形显示出来,当时脑袋一蒙,想着图片加载框架(如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);
    }
}

你可能感兴趣的:(Android种图片圆形化的三种方式)