自定义view系列---通过位图运算实现圆形头像

本篇要讲解一个比较难理解的部分:位图运算。
相信大家都见过下面这张图。
在这里插入图片描述
如果没有理解位图运算的逻辑,上来开始尝试各种模式,就很容易陷入误区,发现自己出来的效果跟这张图完全不相符。下面我们就来详细讲解下位图运算。

一,首先我们要来说一下 图层(layer)的概念。

Canvas在一般情况下可以看做是一张画布,所有的绘图操作如 位图、圆、直线等都在这张画布上绘制。但是如果需要实现一些比较复杂的绘图操作,需要Canvas提供图层的支持。缺省情况下可以看做只有一个图层,如果需要按层次来绘图,Canvas需要创建一些中间层,layer按照“栈结构”来管理。layer入栈时,后续的绘图操作都发生在这个layer上;layer出栈,将本图层绘制的图像绘制到Canvas上。
入栈:创建layer并入栈是通过Canvas的saveLayer方法来实现的。(此方法有比较多的重载类型,大家可根据需要选择)
public int saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags)
出栈:需要调用 public void restoreToCount(int saveCount)方法。

二,位图运算技巧

  1. 准备好分别代表DST和SRC的位图,同时准备第三个位图,用于绘制DST和SRC的运算结果
  2. 创建大小合适的图层入栈
  3. 先将DST位图绘制在第三个位图上
  4. 调用paint的setXfermode()定义位图运算模式
  5. 再将SRC位图绘制在第三个位图上
  6. 清除位图模式
  7. 图层出栈
  8. 将第三个位图绘制在View的Canvas上以便显示出来

三,按照上面的位图运算技巧,我们来实现一个 圆形头像 的自定义view。
我们知道,ImageView是正方形的,但是现在我们看很多APP的用户图像是圆形的,我们可以使用位图运算的 DST_IN 模式来实现

public ComposeShaderView2(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //1,头像Bitmap,是DST
        bmpCat = BitmapFactory.decodeResource(getResources(), R.mipmap.header);//头像bitmap
        //样式Bitmap,是SRC (我们这里准备一个五角星样式的,你可以根据需要改变这个样式)
        bmpCircleMask2 = BitmapFactory.decodeResource(getResources(),R.mipmap.five_start);//五角星样式
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
		//2,按照SRC的大小创建layer,并保存图层ID
        int layer = canvas.saveLayer(0,0,bmpCircleMask2.getWidth(),bmpCircleMask2.getHeight(),null);
		//3,绘制DST
        canvas.drawBitmap(bmpCat,0,0,null);
		//4,设置画笔的模式 setXfermode,为DST_IN,根据实际需求选择模式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
		//5,绘制SRC
        canvas.drawBitmap(bmpCircleMask2,0,0,paint);
		//6,清除位图模式
        paint.setXfermode(null);
        //7,图层出栈(参数为创建涂层时返回的涂层ID)
        canvas.restoreToCount(layer);
    }

R.mipmap.header的原图是
在这里插入图片描述
经过上面的位图计算后效果如下:
在这里插入图片描述
怎么样,是不是将原本方形的图像变成了五角形,当然这里你可以改为任何其他你想要设置的样式。

大家可以根据需要修改步骤4中的位图模式,来完成自已想要的效果。

DONE
此系列后续持续更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值