在Android中绘制时如何遮罩简单区域?
下面是一个简化的描述:假设给我一个视图类,它绘制了一面墙的图片,我想用一个窗口来绘制它。假设我扩展了该视图类并重写其dispatchDraw()方法来执行以下操作。首先画出背景(如果有)以便通过窗口看到。接下来,我想以某种方式屏蔽矩形窗口区域,然后调用super.dispatchDraw()。最后,我想去掉面具,画一个人站在窗前,这样他们就可以在背景和墙上都画出来。我该怎么做 下面是一些代码,它们似乎与我所需要的非常接近:在Android中绘制时如何遮罩简单区域?,android,shape,mask,Android,Shape,Mask,下面是一个简化的描述:假设给我一个视图类,它绘制了一面墙的图片,我想用一个窗口来绘制它。假设我扩展了该视图类并重写其dispatchDraw()方法来执行以下操作。首先画出背景(如果有)以便通过窗口看到。接下来,我想以某种方式屏蔽矩形窗口区域,然后调用super.dispatchDraw()。最后,我想去掉面具,画一个人站在窗前,这样他们就可以在背景和墙上都画出来。我该怎么做 下面是一些代码,它们似乎与我所需要的非常接近: @Override protected void dispatchDra
@Override
protected void dispatchDraw(Canvas into) {
int w = into.getWidth();
int h = into.getHeight();
int w3 = w / 3;
int h3 = h / 3;
into.drawLine(0, 0, w, h, mPaint);
Region protect = new Region(w / 3, h / 3, 2 * w / 3, 2 * h / 3);
into.clipRegion(protect, Op.INTERSECT);
into.drawColor(Color.MAGENTA); // or super.dispatchDraw() here.
}
这给了我这样的信息:
这和我想要的正好相反。注意上面代码中名为“protect”的区域。我希望洋红填充发生在除该区域以外的任何地方。具体来说,我想看到的是:
在窗户的类比中,我应该能够移除限制,以正常的方式画一个人或某物,与窗户和墙壁重叠
编辑:这里是Rajesh CP答案的简化工作版本。我还添加了一条红色的“前景”条纹,画在末尾的所有内容上,以表明我可以删除限制并添加它们。谢谢Rajesh
public class MaskTest extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new ClippView(getApplicationContext()));
}
private class ClippView extends View {
private Paint line_paint = new Paint();
private Paint strip_paint = new Paint();
public ClippView(Context context) {
super(context);
line_paint.setColor(Color.GRAY);
line_paint.setStrokeWidth(20);
strip_paint.setColor(Color.RED);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int w = canvas.getWidth();
int h = canvas.getHeight();
int w3 = w / 3;
int h3 = h / 3;
// This line represents some unknown background that we are drawing over.
canvas.drawLine(0, 0, w, h, line_paint);
// 'protect' represents some area to not paint over until desired.
Region protect = new Region(w3, h3, 2 * w / 3, 2 * h / 3);
canvas.clipRegion(protect, Op.DIFFERENCE);
// Paint magenta over the entire canvas, avoiding the protected region.
canvas.drawColor(Color.MAGENTA);
// Remove the protected region.
Region all = new Region(0, 0, w, h);
canvas.clipRegion(all, Op.UNION);
// Draw a wide foreground strip over the entire canvas.
canvas.drawRect(w / 2 - w / 20, 0, w / 2 + w / 20, h, strip_paint);
}
}
}
我想这就是你想要的。为什么不画四个矩形作为遮罩呢
发布您的代码将非常困难appreciated@RajeshCP,此时没有可共享的代码。我一直在玩弄Canvas.clipPath(路径,Op)方法,这似乎是一个正确的想法,但我还没有找到神奇的图案来指定矩形或其他形状,以保护画布的一个区域不受绘制操作的影响,直到我想在其中绘制/覆盖它。这些链接让我尽我所能,但仍然缺少我正在寻找的关键点。没有一个逻辑“Op”值符合我的要求。您的链接可能会帮助我使用矩形而不是任意路径对象编写更简单的代码,但主要问题仍然存在。查看我添加到问题中的示例代码和图像。我认为我的最大错误是重写dispatchDraw()而不是onDraw()。一个快速的测试显示的不是你给了什么,而是一些开始像我希望的东西。明天我会更加关注,但我想你让我回到了正轨。谢谢你,拉杰什!我在问题描述的末尾添加了您的代码的简化版本。为了简单起见,问题描述使用了矩形区域。我在寻找一个通用的解决方案。
public class ClippView extends View{
private Paint paint= new Paint();
public ClippView(Context context) {
super(context);
}
private Region protect;
/*
* (non-Javadoc)
* @see android.view.View#onDraw(android.graphics.Canvas)
* @since Apr 12, 2013
* @author rajeshcp
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// view.buildDrawingCache();
int w = canvas.getWidth();
int h = canvas.getHeight();
int w3 = w / 3;
int h3 = h / 3;
canvas.drawLine(0, 0, w, h, paint);
protect = (protect == null) ? new Region(w3, h3, 2 * w / 3, 2 * h / 3) : protect;
canvas.clipRegion(protect, Op.DIFFERENCE);
canvas.drawColor(Color.MAGENTA);
}
}