Android: corta un círculo desde un cuadrado

Estoy intentando cortar un círculo de un mapa de bits cuadrado usando código siguiente

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); 

La idea es adjuntar un mapa de bits cuadrado (rectangular) al lienzo y luego recortar una ruta circular. Borrar la diferencia entre el rectángulo y el círculo (hacerlo transparente).

El código funciona bien para Android 4, pero en el dispositivo Android 2.3.3, el área de diferencia está apareciendo en negro más que transparente.

¿Estoy perdiendo algo aquí o PorterDuff.Mode.CLEAR no es compatible con pan de jengibre? ¿Hay una mejor manera de cortar un círculo de un cuadrado en Android?

Parece que PorterDuff.Mode.Clear no funcionó para el pan de jengibre

Resuelto el problema (corte el círculo del cuadrado usando este código)

  Bitmap output = Bitmap.createBitmap(bitmapimg.getWidth(), bitmapimg.getHeight(), 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(Mode.SRC_IN)); canvas.drawBitmap(bitmapimg, rect, rect, paint); return output; 
 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; } 

Para cualquier persona que todavía está mirando esto, esta respuesta causará algunos problemas.

1.) El lienzo que está creando en esta instancia no tendrá aceleración de hardware. A pesar de que su objeto de pintura tiene anti-aliasing, el lienzo no. Esto causará artefactos cuando decida pintar esto de nuevo a su lienzo original en su llamada onDraw ().

2.) Esto requiere mucho más recursos. Tienes que crear un segundo Bitmap (que puede causar OOM), y un lienzo secundario, así como todas las diferentes alteraciones que tienes que hacer.

Por favor, compruebe la respuesta de Romain Guy. Crea un BitmapShader y luego crea un RoundRect que le da un Círculo. Sólo necesita conocer las dimensiones de su RectF para que pueda determinar el círculo correctamente.

Esto significa que si conoce el punto central (x, y) y el radio, puede determinar fácilmente el RectF.

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

Esto también significa que con esta solución que aparece a continuación sólo tiene que dibujar a la pantalla una vez, todo lo demás se hace en el búfer fuera de pantalla.

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

La mejor solución se encuentra aquí:

 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); 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.