La mia soluzione è vicina alla soluzione di @ over_optimistic, meno una chiamata saveLayer(). Io uso una maschera Drawable invece di un percorso, nel mio caso era un disco.
ho dichiarato queste variabili come campi (è buona pratica per allocare la memoria al di fuori del metodo OnDraw):
private Paint maskingPaint = new Paint();
private Drawable mask = <insert your drawable here>
Poi, da qualche parte al di fuori di OnDraw(), impostazione degli oggetti:
// 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>);
infine, l'OnDraw() metodo applica la maschera:
@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();
}
Per una migliore comprensione o Per le modalità di trasferimento, ho fatto riferimento a http://ssp.impulsetrain.com/porterduff.html. Questa pagina è piuttosto interessante da leggere. Dopodiché, con lo stesso tipo di codice sarai in grado di ottenere molto più di una semplice maschera!
fonte
2014-07-30 16:04:05
Sto cercando di utilizzare le parti nere della maschera bitmap per impostare il canale alfa del pixel corrispondente sull'altra bitmap/Drawable su 0. –