我有一个应用程序要求整个RelativeLayout(现在是扩展它的自定义视图)需要使用自定义图像进行蒙版。布局中有许多视图需要通过触摸访问并且是动态的。
我已成功使用另一个问题的答案屏蔽了区域绘图形状:
@Override
protected void dispatchDraw(Canvas canvas) {
Path path = new Path();
int count = canvas.save();
path.addCircle(400, 200, 300, Path.Direction.CW);
canvas.clipPath(path);
super.dispatchDraw(canvas);
canvas.restoreToCount(count);
}
但是,我需要使用图像源作为我的蒙版源而不是我可以创作的形状。我使用PorterDuff工具包来改变位图:
Bitmap resizedBitmap = Bitmap.createScaledBitmap(mMask, this.getWidth(), this.getHeight(), false);
Bitmap result = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888); //create another bitmap with same height
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(resizedBitmap, 0, 0, paint);
paint.setXfermode(null);
onDrawCanvas.drawBitmap(result, 0,0, paint);
这适用于屏蔽图像,但我需要使用Clip进行屏蔽(我认为)。有没有办法使用不同的PorterDuff模式从此图像派生路径?或者是否有一个更简单的方法,就像在iOS中你可以直接用图像设置layerMask?提前谢谢。
答案 0 :(得分:2)
框架中没有直接的API允许您跟踪实体图像蒙版并生成可用于剪切的Path
。如果您可以将掩码内容作为SVG访问,则可以使用Romain Guy在此处描述的路径跟踪技术:
http://www.curious-creature.org/2013/12/21/android-recipe-4-path-tracing/
虽然这不是我最喜欢的技术,但我见过的最佳选择基本上是你已经描述的项目的组合。我们需要创建一个可以渲染视图内容的离屏缓冲区(通过Canvas + Bitmap),然后使用传输模式技术将结果应用到附加到窗口的Canvas上。我没有尝试使用ViewGroup
发送,但它应该工作。以下(未经测试的)代码将是一个起点:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw || h != oldh) {
//Create an area to use for content rendering
mCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mCanvasBitmap);
mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
//Render contents into our buffer
super.dispatchDraw(mCanvas);
//Render the mask, clipping with a PorterDuffXfermode
paint.setXfermode(mXfermode);
mCanvas.drawBitmap(mMask, 0, 0, paint);
//Clear state and transfer result
paint.setXfermode(null);
canvas.drawBitmap(mCanvasBitmap, 0, 0, paint);
}
这种方法的一个缺点是记忆;如果视图足够大,则必须分配一个等于视图容器大小的额外块。我们可以通过执行一次并重用缓冲区来最小化这种影响。