在Android上如何制作奇形怪状的剪裁区域?

Hap*_*eer 18 android dalvik masking android-canvas

以下是如何创建圆形的剪裁区域:

Path path = new Path();
path.addCircle(200,200,100,Direction.CW);
c.clipPath(path); // c is a Canvas
Run Code Online (Sandbox Code Playgroud)

现在Canvas上有一个剪裁区域,可以防止在该圆圈范围之外绘制任何东西.但是,如果我想将剪裁区域塑造成甜甜圈(或其他),该怎么办?

我尝试使用创建第二个Path并在其上使用toggleInverseFillType,然后将其添加到原始路径,但这似乎不起作用.

或者,不是使用Path,而是可以创建一个Bitmap用作蒙版,并以某种方式将其设置为Canvas上的剪贴蒙版?

编辑:答案正是我需要一个小的补充.在画布上执行多个操作时,请始终在第一个clipPath调用上使用Op.REPLACE.这将替换该Canvas上的任何现有clipPath.

作为参考,我在这里发现了6个不同的Region.Op值的含义.想象一下有2个圆圈的维恩图."B"是2个圆圈重叠的部分."A"是不重叠的左圆."C"是不重叠的右圆.

c.clipPath(a,Region.Op.REPLACE);
c.clipPath(b,???);

Region.Op.DIFFERENCE         -> A..            
Region.Op.INTERSECT          -> .B.            
Region.Op.REPLACE            -> .BC            
Region.Op.REVERSE_DIFFERENCE -> ..C            
Region.Op.UNION              -> ABC
Region.Op.XOR                -> A.C
Run Code Online (Sandbox Code Playgroud)

"." 表示未绘制的部分.对不起,如果不是特别清楚.没有图形很难很好地描述.

jar*_*rad 18

来自Canvas javadoc:

Canvas#clipPath(Path path, Region.Op op) - 使用指定的路径修改当前剪辑.

所以,对于你的甜甜圈示例:

  1. 创建2个路径.一个用于较大的圆圈,一个用于较小的圆圈.
  2. Canvas#clipPath( Path )用更大的圆圈Path.
  3. Canvas#clipPath( Path, Region.Op )在画布上调用方法Path,第一个参数的小圆圈和Region.Op第二个参数的相应枚举值.

    Path largePath = new Path();
    largePath.addCircle(200,200,100,Direction.CW);
    Path smallPath = new Path();
    smallPath.addCircle(200,200,40,Direction.CW);
    c.clipPath(largePath); // c is a Canvas
    c.clipPath(smallPath, Region.Op.DIFFERENCE);
    
    Run Code Online (Sandbox Code Playgroud)

再次,修改Region.Op枚举值以获得不同的效果......

  • 很好,`// c是Canvas`那么为什么不是'canvas`呢?当Androdi工作室几乎预测你想要输入什么时,为什么要偷懒? (3认同)
  • 如果您为视图/活动/应用程序禁用硬件加速,则支持Clippath就好了.Android 4+的不同之处在于默认情况下启用了HA. (2认同)