studio resource from example android bitmap mask drawable

android - resource - drawable to bitmap



Enmascarar un Drawable/Bitmap en Android (5)

Hice un diseño enmascarable. Es un framelayout donde puedes especificar el modo xporterduffmode y la máscara. Lo puedes encontrar aquí: https://github.com/christophesmet/android_maskable_layout

Actualmente estoy buscando una forma de usar un mapa de bits en blanco y negro para enmascarar el canal alfa de otro mapa de bits o Dibujable en Android. Tengo curiosidad por saber cuál es la mejor manera de hacer esto. Ciertamente tengo un par de ideas sobre cómo hacer esto, pero no son óptimas.

Necesito poder aplicar una nueva máscara a la imagen de vez en cuando (el mapa de bits en blanco y negro cambiará cada pocos segundos).

Cualquier comentario sobre cómo lograr esto sería muy apreciado.


Lo tengo funcionando, así que es algo como esto.

// 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();


Mi solución está cerca de la solución de @ over_optimistic, menos una llamada a saveLayer (). Utilizo una máscara dibujable en lugar de una ruta, en mi caso era un disco.

Declaré estas variables como campos (es una buena práctica asignar memoria fuera del método onDraw):

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

Luego, en algún lugar fuera de onDraw (), configure los objetos:

// 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>);

Entonces, finalmente, el método onDraw () aplica la máscara:

@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(); }

Para una mejor comprensión de los modos de transferencia, me referí a http://ssp.impulsetrain.com/porterduff.html . Esa página es bastante interesante de leer. Después de eso, con el mismo tipo de código podrás lograr mucho más que una simple máscara.


No tengo muy claro qué es lo que está buscando, pero creo que puede funcionar una combinación de BitmapDrawable y LayerDrawable . BitmapDrawable te permitirá usar tus mapas de bits como Drawables, y luego puedes usar LayerDrawable para colocar la máscara sobre otro Drawable.


Usando el ejemplo de Xfermodes en la Demo API, pude usar un PorterDuffXfermode aplicado a un objeto Paint para mezclar dos mapas de bits en un lienzo. Esto funciona exactamente como lo necesito.