在Android上遮盖可绘制/位图

我目前正在寻找一种方法来使用黑白位图掩盖另一个位图或Android上的Drawable的alpha通道。 我很好奇最好的办法是做什么。 对于如何做到这一点,我当然有一些想法,但他们不是最佳的。

我需要能够每隔一段时间对图像应用一个新的遮罩(黑白图像每隔几秒就会改变一次)。

任何有关如何实现这一点的反馈将不胜感激。

Solutions Collecting From Web of "在Android上遮盖可绘制/位图"

我得到了它的工作,所以这是这样的

// we first same the layer, rectF is the area of interest we plan on drawing // this will create an offscreen bitmap canvas.saveLayer(rectF, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); // draw our unmasked stuff super.draw(canvas); // We same a layer again but this time we pass a paint object to mask // the above layer maskPaint = new Paint() maskPaint.setColor(0xFFFFFFFF); maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); canvas.saveLayer(rectF, maskPaint, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); // we draw the mask which is black and white. In my case // I have a path, and I use a blurPaint which blurs the mask slightly // You can do anti aliasing or whatever you which. Just black & white canvas.drawPath(path, blurPaint); // We restore twice, this merges the results upward // as each saveLayer() allocates a new drawing bitmap canvas.restore(); canvas.restore(); 

我的解决scheme接近@ over_optimistic的解决scheme,less一个saveLayer()调用。 我使用可绘制的蒙版,而不是一个path,在我的情况下,它是一个光盘。

我将这些variables声明为字段(这是在onDraw方法之外分配内存的好习惯):

 private Paint maskingPaint = new Paint(); private Drawable mask = <insert your drawable here> 

然后,在onDraw()以外的地方设置对象:

 // Xfermode won't work if hardware accelerated setLayerType(View.LAYER_TYPE_SOFTWARE, null); // Using destination shape as a mask // For a good explanation of PorterDuff transfer modes : http://ssp.impulsetrain.com/porterduff.html maskingPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); maskingPaint.setAntiAlias(true); // Position the mask mask.setBounds(<insert your mask bounds here>); 

最后,onDraw()方法应用掩码:

 @Override protected synchronized void onDraw(Canvas canvas) { // Draw the mask first, making it the PorterDuff destination mask.draw(canvas); // Save the layer with the masking paint, that will be applied on restore() // Using CLIP_TO_LAYER_SAVE_FLAG to avoid any overflow of the masked image outside the mask bounds. Rect bounds = mask.getBounds(); canvas.saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, maskingPaint, Canvas.CLIP_TO_LAYER_SAVE_FLAG); // Draw the shape offscreen, making it the PorterDuff source super.onDraw(canvas); // Apply the source to the destination, using SRC_IN transfer mode canvas.restore(); } 

为了更好地理解传输模式,我参考了http://ssp.impulsetrain.com/porterduff.html 。 该页面非常有趣。 之后,使用相同types的代码,您将能够获得比单纯的面具更多的function!

我做了一个可屏蔽的布局。 这是一个框架布局,您可以在其中指定xporterduffmode和掩码。 你可以在这里find它: https : //github.com/christophesmet/android_maskable_layout

我不完全清楚你要做什么,但我相信, BitmapDrawableLayerDrawable的组合可能工作。 BitmapDrawable将允许您使用您的位图作为Drawables,然后您可以使用LayerDrawable将遮罩层叠在另一个Drawable上。

在API Demo中使用Xfermodes示例,我可以使用应用于Paint对象的PorterDuffXfermode在canvas上混合两个位图。 这工作正是我需要它。