Ho una visione che fa un po 'di disegno di base. Dopodiché voglio disegnare un rettangolo con un foro punzonato in modo che sia visibile solo una regione del disegno precedente. E mi piacerebbe farlo con l'accelerazione hardware abilitata per la mia vista per le migliori prestazioni.fare un buco in una sovrapposizione rettangolo con l'accelerazione hardware abilitata su Visualizza
Attualmente ho due metodi che funzionano, ma funziona solo quando l'accelerazione hardware è disabilitata e l'altro è troppo lento.
Metodo 1: SW Accelerazione (lento)
final int saveCount = canvas.save();
// Clip out a circle.
circle.reset();
circle.addCircle(cx, cy, radius, Path.Direction.CW);
circle.close();
canvas.clipPath(circle, Region.Op.DIFFERENCE);
// Draw the rectangle color.
canvas.drawColor(backColor);
canvas.restoreToCount(saveCount);
Questo non funziona con accelerazione hardware abilitato per la vista perché 'canvas.clipPath' non è supportato in questa modalità (So che posso forzare Rendering SW, ma vorrei evitarlo).
Metodo 2: accelerazione HW (V. Lento)
// Create a new canvas.
final Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(b);
// Draw the rectangle colour.
c.drawColor(backColor);
// Erase a circle.
c.drawCircle(cx, cy, radius, eraser);
// Draw the bitmap on our views canvas.
canvas.drawBitmap(b, 0, 0, null);
Dove viene creato gomma come
eraser = new Paint()
eraser.setColor(0xFFFFFFFF);
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
Questo è ovviamente lento - un nuovo Bitmap
la dimensione della vista è creato ogni chiamata di disegno.
Metodo 3: accelerazione HW (veloce, non funziona su alcuni dispositivi)
canvas.drawColor(backColor);
canvas.drawCircle(cx, cy, radius, eraser);
Stesso come il metodo compatibile con l'accelerazione hardware, ma nessuna tela di canapa supplementare richiesto. Tuttavia c'è un grosso problema: funziona con il rendering SW forzato, ma su HTC One X (Android 4.0.4 - e probabilmente con qualche altro dispositivo) almeno con il rendering HW abilitato lascia il cerchio completamente nero. Questo è probabilmente correlato a 22361.
Metodo 4: HW accelerazione (Accettabile, funziona su tutti i dispositivi)
Come da suggerimento di gennaio per migliorare il metodo 2, ho evitato di creare la bitmap in ogni chiamata a onDraw
, invece di farlo in onSizeChanged
:
if (w != oldw || h != oldh) {
b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
c = new Canvas(b);
}
E poi basta utilizzare questi in onDraw
:
if (overlayBitmap == null) {
b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
c = new Canvas(b);
}
b.eraseColor(Color.TRANSPARENT);
c.drawColor(backColor);
c.drawCircle(cx, cy, radius, eraser);
canvas.drawBitmap(b, 0, 0, null);
La prestazione non è buono come il metodo 3, ma molto meglio di 2 e un po 'meglio di 1.
La domanda
Come posso ottenere lo stesso effetto, ma farlo in un modo compatibile con Accelerazione HW (E che funziona in modo coerente sui dispositivi)? Un metodo che aumenta le prestazioni di rendering SW sarebbe anche accettabile.
NB: quando si sposta il cerchio attorno, invalido solo una regione, non l'intera tela, quindi non c'è spazio per un miglioramento delle prestazioni.
è semplicemente la memorizzazione nella cache del 'B' Bitmap e' C' Canvas possibile? Sarebbe d'aiuto? –
Io non la penso così - se fai semplicemente la 'b' e' c' di dire in 'onSizeChanged' e non in 'onDraw', finirai per disegnare più volte sulla stessa tela senza cancellare (così faresti finire con più livelli). In realtà funzionerebbe se potessi cancellare 'b' in' onDraw', che potrebbe essere possibile - ci proverò, grazie! –
@Jan: Grazie a questo ha funzionato - Ho creato il bitmap 'b' e Canvas' c' in 'onSizeChanged', quindi ho solo dovuto chiamare' b.eraseColor (Color.Transparent) 'prima di fare qualsiasi disegno per cancellare qualsiasi precedente disegno su 'c'. Pubblica il tuo commento come risposta e lo segnerò correttamente se non ricevo più risposte utili nel giorno successivo. Non è ancora così fluido come il metodo 3, ma molto meglio di 2. –