2012-12-02 7 views
16

Ich versuche, eine Canvas-Zeichenoperation in einen bogenförmigen Keil zu schneiden. Das beabsichtigte Ergebnis wird jedoch nicht angezeigt, nachdem der Beschneidungspfad auf der Leinwand festgelegt wurde.Canvas.clipPath (Pfad) schneidet nicht wie erwartet ab

Zur Veranschaulichung hier ist, was ich tue:

enter image description here

path.reset(); 

//Move to point #1 
path.moveTo(rect.centerX(), rect.centerY()); 

//Per the documentation, this will draw a connecting line from the current 
//position to the starting position of the arc (at 0 degrees), add the arc 
//and my current position now lies at #2. 
path.arcTo(rect, 0, -30); 

//This should then close the path, finishing back at the center point (#3) 
path.close(); 

Dies funktioniert, und wenn ich einfach diesen Weg zeichnen (canvas.drawPath(path, paint)) zieht den Keil wie oben gezeigt. Allerdings, wenn ich diesen Pfad als Beschneidungspfad der Leinwand gesetzt und hinein ziehen:

//I've tried it with and without the Region.Op parameter 
canvas.clipPath(path, Region.Op.REPLACE); 
canvas.drawColor(Color.BLUE); 

ich folgendes Ergebnis stattdessen bekommen (der Keil bleibt nur Referenz zeigen):

enter image description here

So scheint es stattdessen an die Grenze der Path Clip, und nicht die Path selbst zu klammern. Irgendwelche Ideen was hier passiert?

BEARBEITEN Nur als ein Update, ich habe eine viel effizientere Möglichkeit gefunden, dies zu tun, die Hardware-Beschleunigung ermöglicht. Zeichnen Sie zuerst das gesamte Bild (das Sie schneiden würden) in eine Bitmap im Offscreen-Format. Machen Sie eine BitmapShader dieses Bitmap verwenden, setzen Sie diese Shader auf ein Paint, dann den Keil Weg ziehen mit, dass Paint Objekt:

drawMyBitmap(bitmap); 
Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
paint.setShader(shader); 

@Override 
public void onDraw(Canvas canvas) { 
    canvas.drawArc(rect,   //The rectangle bounding the circle 
        startAngle, //The angle (CW from 3 o'clock) to start 
        sweepAngle, //The angle (CW from 3 o'clock) of the arc 
        true,   //Boolean of whether to draw a filled arc (wedge) 
        paint   //The paint with the shader attached 
    ); 
} 
+1

Stehen Sie mit HC oder höher oder anderweitig Hardwarebeschleunigung verwenden? http://developer.android.com/guide/topics/graphics/hardware-accel.html. Wenn dies der Fall ist, wird clipPath nicht unterstützt und ist problematisch. – Simon

+1

@Simon: Oh mein Gott. Heh. Leider habe ich diese Woche viel auf dieses Dokument Bezug genommen, aber das habe ich völlig übersehen. Deaktivieren von HW Accel hat perfekt funktioniert! Wenn du das als Antwort postest, akzeptiere ich es. Du bist ein Lebensretter! – kcoppock

+0

Ich bin froh, dass ich geholfen habe. Viel Glück. – Simon

Antwort

9

Sie HC oder höher oder auf andere Weise unter Verwendung von Hardwarebeschleunigung verwenden?

Wenn ja, ist ClipPath nicht unterstützt und problematisch.

developer.android.com/guide/topics/graphics/hardware-accel.html.

+1

Das war das Problem. :) Der Clipping-Teil der Zeichenoperation wurde in eine Offscreen-Bitmap verschoben und dann zurück auf die HW-beschleunigte Leinwand gezogen, und das funktioniert wie ein Zauber! Danke noch einmal! – kcoppock

+1

@kcoppock Das klingt ein bisschen nach hinten. Warum konvertierst du nicht einfach den Layer-Typ der Ansicht in Software und machst deine Zeichnung trotzdem in 'onDraw()'? –

+0

@ RichardJ.RossIII Das hätte mehr Sinn gemacht.:) Das war mir damals noch nicht so vertraut. Ich habe auf die neue Art editiert, dass ich jetzt dieses Problem behandle, danke für die Eingabe! – kcoppock

2

OPs Frage bezieht sich speziell auf die Verwendung einer Clipping-Region und wurde von @Simon beantwortet. Denken Sie jedoch daran, dass es ein einfacherer Weg, um einen gefüllten Bogen zeichnen:

erstellen Paint:

mPaint = new Paint(); 
mPaint.setColor(Color.BLUE); 
mPaint.setStyle(Style.FILL); 
mPaint.setAntiAlias(true); 

Beim Zeichnen Sie einfach den Pfad zeichnen:

canvas.drawPath(path, mPaint); 
Verwandte Themen