Meine Lösung ist in der Nähe von @ over_optimistic Lösung, weniger einen saveLayer() Anruf. Ich benutze eine Drawable-Maske anstelle eines Pfades, in meinem Fall war es eine Disc.
erklärte ich diese Variablen als Felder (es ist gute Praxis Speicher außerhalb der OnDraw-Methode zuzuteilen):
private Paint maskingPaint = new Paint();
private Drawable mask = <insert your drawable here>
Dann irgendwo außerhalb von OnDraw(), Einrichtung der Objekte:
// 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>);
Dann wendet die Methode onDraw() schließlich die Maske an:
@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();
}
Für ein besseres Verständnis o Für die Übertragungsmodi habe ich auf http://ssp.impulsetrain.com/porterduff.html verwiesen. Diese Seite ist ziemlich interessant zu lesen. Danach können Sie mit der gleichen Art von Code viel mehr erreichen als nur eine einfache Maske!
Ich versuche, die schwarzen Teile der Maske Bitmap verwenden, um den Alpha-Kanal des entsprechenden Pixels auf der anderen Bitmap/Drawable auf 0 setzen. –