2012-11-08 13 views
15

Ich versuche, einen Kreis aus einem quadratischen Bitmap zu schneiden folgenden Code verwendenAndroid - Schneiden Sie einen Kreis aus einem Quadrat Bitmap

 Canvas canvas=new Canvas(bitmapimg); 
     int circleXCoord = bitmapimg .getWidth()/2; 
     int circleYCoord = bitmapimg .getHeight()/2; 
     int circleRadius = bitmapimg .getWidth()/2; 

     Rect rect = new Rect(circleXCoord - circleRadius, circleYCoord - circleRadius, circleXCoord + circleRadius, circleYCoord + circleRadius); 

     int width = rect.width(); 
     int height = rect.height(); 

     Paint paint = new Paint(); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setColor(Color.BLUE); 
     canvas.drawRect(rect, paint); 
     canvas.drawBitmap(bitmapimg , rect, rect, paint); 
     Path p = new Path(); 
     p.addCircle(circleXCoord, circleYCoord, width/2F, Path.Direction.CW); 
     canvas.clipPath(p, Region.Op.DIFFERENCE); 
     canvas.drawColor(0, PorterDuff.Mode.CLEAR); 

Die Idee ist, eine quadratische (rechteckig) Bitmap befestigen auf die Leinwand und dann einen Clip kreisförmiger Pfad. Löschen Sie den Unterschied zwischen dem Rechteck und dem Kreis (machen Sie es transparent).

Der Code funktioniert gut für Android 4, aber auf Android 2.3.3-Gerät, der Unterschied Bereich erscheint eher schwarz, dass transparent.

Fehle ich etwas hier oder PorterDuff.Mode.CLEAR wird nicht in Lebkuchen unterstützt? Gibt es eine bessere Möglichkeit, einen Kreis von einem Quadrat in Android zu schneiden?

Antwort

36

Scheint wie PorterDuff.Mode.Clear nicht für Lebkuchen funktionierten

das Problem gelöst (Schnittkreis von Platz mit diesem Code)

public Bitmap BitmapCircularCroper(Bitmap bitmapimg){ 
    Bitmap output = Bitmap.createBitmap(bitmapimg.getWidth(), 
      bitmapimg.getHeight(), Bitmap.Config.ARGB_8888); 
    Canvas canvas = new Canvas(output); 

    final int color = 0xff424242; 
    final Paint paint = new Paint(); 
    final Rect rect = new Rect(0, 0, bitmapimg.getWidth(), 
      bitmapimg.getHeight()); 

    paint.setAntiAlias(true); 
    canvas.drawARGB(0, 0, 0, 0); 
    paint.setColor(color); 
    canvas.drawCircle(bitmapimg.getWidth()/2, 
      bitmapimg.getHeight()/2, bitmapimg.getWidth()/2, paint); 
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
    canvas.drawBitmap(bitmapimg, rect, rect, paint); 
    return output; 

} 
+0

Kreis Bitmap bekommen, aber warum Platz transparenter Bereich in meinem Fall schwarz dargestellt? – Ram

2

Für alle, die in diesem noch schaut, diese Antwort wird ein paar Probleme verursachen.

1.) Die Leinwand, die Sie in diesem Fall erstellen, wird keine Hardwarebeschleunigung haben. Auch wenn Ihr Paint-Objekt Anti-Aliasing aufweist, wird dies nicht möglich sein. Dies führt zu Artefakten, wenn Sie diese in Ihrem onDraw() - Aufruf zurück auf Ihre ursprüngliche Zeichenfläche malen.

2.) Dies erfordert viel mehr Ressourcen. Sie müssen ein zweites Bitmap (das OOM verursachen kann) und ein zweites Canvas sowie alle anderen Änderungen, die Sie vornehmen müssen, erstellen.

Bitte überprüfen Sie die Antwort von Romain Guy. Sie erstellen einen BitmapShader und erstellen dann einen RoundRect, der Ihnen einen Kreis gibt. Sie müssen nur die Abmessungen Ihres RectF kennen, damit er den Kreis richtig bestimmen kann.

Das heißt, wenn Sie den Mittelpunkt (x, y) und den Radius kennen, können Sie das RectF leicht bestimmen.

left = x - radius; 
top = y - radius; 
right = x + radius; 
bottom = y + radius; 

auch Das bedeutet, dass mit dieser Lösung unter euch auf dem Laufenden nur einmal auf dem Bildschirm zu zeichnen haben, alles andere ist in der Off-Screen-Puffer durchgeführt.

http://www.curious-creature.com/2012/12/11/android-recipe-1-image-with-rounded-corners/

Die beste Lösung ist hier zu finden:

BitmapShader shader; 
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 

Paint paint = new Paint(); 
paint.setAntiAlias(true); 
paint.setShader(shader); 

RectF rect = new RectF(0.0f, 0.0f, width, height); 

// rect contains the bounds of the shape 
// radius is the radius in pixels of the rounded corners 
// paint contains the shader that will texture the shape 
canvas.drawRoundRect(rect, radius, radius, paint); 
+0

Sehr nützlich, um ein kreisförmiges Foto als das große Symbol einer Benachrichtigung zu zeichnen, die eine Bitmap sein muss. Vielen Dank – user3175580

3
import android.graphics.PorterDuff.Mode; 
import android.graphics.Bitmap.Config; 

public static Bitmap getCircularBitmap(Bitmap bitmap) 
{ 
    Bitmap output; 

    if (bitmap.getWidth() > bitmap.getHeight()) { 
     output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Config.ARGB_8888); 
    } else { 
     output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Config.ARGB_8888); 
    } 

    Canvas canvas = new Canvas(output); 

    final int color = 0xff424242; 
    final Paint paint = new Paint(); 
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 

    float r = 0; 

    if (bitmap.getWidth() > bitmap.getHeight()) { 
     r = bitmap.getHeight()/2; 
    } else { 
     r = bitmap.getWidth()/2; 
    } 

    paint.setAntiAlias(true); 
    canvas.drawARGB(0, 0, 0, 0); 
    paint.setColor(color); 
    canvas.drawCircle(r, r, r, paint); 
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
    canvas.drawBitmap(bitmap, rect, rect, paint); 

    return output; 
} 
Verwandte Themen