¿Cómo hacer un ImageView con esquinas redondeadas?

En Android, un ImageView es un rectángulo por defecto. ¿Cómo puedo convertirlo en un rectángulo redondeado (recortar las 4 esquinas de mi bitmap para que sean rectangularjs redondeados) en ImageView?

Esto es bastante tarde en respuesta, pero para cualquier otra persona que esté buscando esto, puede hacer el siguiente código para redondear manualmente las esquinas de sus imágenes.

http://www.ruibm.com/?p=184

Este no es mi código, pero lo he usado y funciona maravillosamente. Lo utilicé como ayudante dentro de una clase ImageHelper y lo extendí solo un poco para pasar la cantidad de graduación que necesito para una imagen dada.

El código final se ve así:

package com.company.app.utils; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Bitmap.Config; import android.graphics.PorterDuff.Mode; public class ImageHelper { public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap .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, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } } 

¡Espero que esto ayude a alguien!

Si bien la respuesta anterior funciona, Romain Guy (un desarrollador principal de Android) muestra un método mejor en su blog que usa menos memoria al usar un sombreador que no crea una copia del bitmap. La esencia general de la funcionalidad está 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); 

Las ventajas de esto sobre otros métodos es que:

  • no crea una copia separada del bitmap, que usa mucha memoria con imágenes grandes [frente a la mayoría de las otras respuestas aquí]
  • admite antialisasing [vs método ClipPath]
  • admite el método alfa [vs xfermode + porterduff]
  • admite aceleración de hardware [vs método de clipPath]
  • solo se dibuja una vez en el canvas [vs xfermode y métodos de clippath]

Creé un RoundedImageView basado en este código que envuelve esta lógica en un ImageView y agrega el soporte adecuado de ScaleType y un borde redondeado opcional.

En la v21 de la biblioteca de Soporte, ahora hay una solución para esto: se llama RoundedBitmapDrawable .

Básicamente es como un Drawable normal, excepto que le das un radio de esquina para el recorte con:

 setCornerRadius(float cornerRadius) 

Entonces, comenzando con Bitmap src y un objective ImageView , se vería algo como esto:

 RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src); dr.setCornerRadius(cornerRadius); imageView.setImageDrawable(dr); 

Otra manera fácil es usar un CardView con el radio de la esquina y un ImageView adentro:

     

enter image description here

El recorte a formas redondeadas se agregó a la clase View en API 21.

Solo haz esto:

  • Crea una forma redondeada dibujable, algo como esto:

res / drawable / round_outline.xml

   ...  
  • Establezca el dibujable como fondo de su ImageView: android:background="@drawable/round_outline"
  • De acuerdo con esta documentación , todo lo que necesitas hacer es agregar android:clipToOutline="true"

Lamentablemente, hay un error y ese atributo XML no se reconoce. Afortunadamente, aún podemos configurar el recorte en Java:

  • En su actividad o fragmento: ImageView.setClipToOutline(true)

Esto es lo que se verá:

enter image description here

Nota:

Este método funciona para cualquier forma dibujable (no solo redondeada). Cortará el ImageView a cualquier contorno de forma que haya definido en su Drawable xml.

Nota especial sobre ImageViews

setClipToOutline() solo funciona cuando el fondo de la Vista se establece en una forma dibujable. Si esta forma de fondo existe, View trata el contorno de la forma como los bordes para fines de recorte y sombreado.

Esto significa que, si desea usar setClipToOutline() para redondear las esquinas en un ImageView, su imagen debe establecerse usando android:src lugar de android:background (ya que el fondo debe configurarse en su forma redondeada). Si DEBE usar el fondo para establecer su imagen en lugar de src, puede usar esta solución alternativa:

  • Crea un diseño y establece su fondo a tu forma dibujable
  • Envuelva ese diseño alrededor de su ImageView (sin relleno)
  • El ImageView (incluido todo lo demás en el diseño) ahora se mostrará con forma de diseño redondeado.

Descubrí que ambos métodos fueron muy útiles para encontrar una solución funcional. Aquí está mi versión compuesta, que es independiente de píxeles y le permite tener algunas esquinas cuadradas con el rest de las esquinas con el mismo radio (que es el caso de uso habitual). Gracias a las dos soluciones anteriores:

 public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR ) { Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888); Canvas canvas = new Canvas(output); final float densityMultiplier = context.getResources().getDisplayMetrics().density; final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, w, h); final RectF rectF = new RectF(rect); //make sure that our rounded corner is scaled appropriately final float roundPx = pixels*densityMultiplier; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); //draw rectangles over the corners we want to be square if (squareTL ){ canvas.drawRect(0, h/2, w/2, h, paint); } if (squareTR ){ canvas.drawRect(w/2, h/2, w, h, paint); } if (squareBL ){ canvas.drawRect(0, 0, w/2, h/2, paint); } if (squareBR ){ canvas.drawRect(w/2, 0, w, h/2, paint); } paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(input, 0,0, paint); return output; } 

Además, eliminé ImageView para incluirlo y poder definirlo en xml. Es posible que desee agregar algo de la lógica que hace la llamada estupenda, pero la he comentado ya que no es útil en mi caso.

  @Override protected void onDraw(Canvas canvas) { //super.onDraw(canvas); Drawable drawable = getDrawable(); Bitmap b = ((BitmapDrawable)drawable).getBitmap() ; Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); int w = getWidth(), h = getHeight(); Bitmap roundBitmap = CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false); canvas.drawBitmap(roundBitmap, 0,0 , null); } 

¡Espero que esto ayude!

Imagen redondeada usando ImageLoader aquí

Crear DisplayImageOptions :

 DisplayImageOptions options = new DisplayImageOptions.Builder() // this will make circle, pass the width of image .displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu))) .cacheOnDisc(true) .build(); imageLoader.displayImage(url_for_image,ImageView,options); 

O puede usar la Biblioteca Picasso desde Square.

 Picasso.with(mContext) .load(com.app.utility.Constants.BASE_URL+b.image) .placeholder(R.drawable.profile) .error(R.drawable.profile) .transform(new RoundedTransformation(50, 4)) .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size) .centerCrop() .into(v.im_user); 

puedes descargar el archivo RoundedTransformation aquí aquí

Lo he hecho por Custom ImageView:

 public class RoundRectCornerImageView extends ImageView { private float radius = 18.0f; private Path path; private RectF rect; public RoundRectCornerImageView(Context context) { super(context); init(); } public RoundRectCornerImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RoundRectCornerImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { path = new Path(); } @Override protected void onDraw(Canvas canvas) { rect = new RectF(0, 0, this.getWidth(), this.getHeight()); path.addRoundRect(rect, radius, radius, Path.Direction.CW); canvas.clipPath(path); super.onDraw(canvas); } } 

Cómo utilizar:

  

Salida:

enter image description here

Espero que esto te ayude.

Como todas las respuestas parecían demasiado complicadas para mí solo para las esquinas redondas, pensé y encontré otra solución que creo que vale la pena compartir, solo con XML en caso de que tengas algo de espacio alrededor de la imagen:

Crea una forma delimitada con contenido transparente como este:

      

Luego, en RelativeLayout, primero puede colocar su imagen y luego en la misma ubicación sobre la forma con otra ImageView. La forma de la cubierta debe ser de mayor tamaño por la cantidad del ancho del borde. Tenga cuidado de tomar un radio de esquina más grande cuando se define el radio exterior, pero el radio interno es lo que cubre su imagen.

Espero que ayude a alguien también.

Edite según CQM solicite el ejemplo de diseño relativo:

      

Mi implementación de ImageView con el widget de esquinas redondeadas, que (hacia abajo || arriba) ajusta la imagen a las dimensiones requeridas. Utiliza el código de forma CaspNZ.

 public class ImageViewRounded extends ImageView { public ImageViewRounded(Context context) { super(context); } public ImageViewRounded(Context context, AttributeSet attrs) { super(context, attrs); } public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { BitmapDrawable drawable = (BitmapDrawable) getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } Bitmap fullSizeBitmap = drawable.getBitmap(); int scaledWidth = getMeasuredWidth(); int scaledHeight = getMeasuredHeight(); Bitmap mScaledBitmap; if (scaledWidth == fullSizeBitmap.getWidth() && scaledHeight == fullSizeBitmap.getHeight()) { mScaledBitmap = fullSizeBitmap; } else { mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap, scaledWidth, scaledHeight, true /* filter */); } Bitmap roundBitmap = ImageUtilities.getRoundedCornerBitmap(getContext(), mScaledBitmap, 5, scaledWidth, scaledHeight, false, false, false, false); canvas.drawBitmap(roundBitmap, 0, 0, null); } } 

Debe extender ImageView y dibujar su propio rectángulo redondeado.

Si desea un marco alrededor de la imagen, también podría superponer el marco redondeado en la parte superior de la vista de la imagen en el diseño.

[edit] Superponga el marco sobre la imagen original, usando un FrameLayout por ejemplo. El primer elemento de FrameLayout será la imagen que desea mostrar redondeada. A continuación, agregue otro ImageView con el marco. El segundo ImageView se mostrará sobre el ImageView original y, por lo tanto, Android dibujará sus contenidos sobre el original ImageView .

Apoyos a George Walters II arriba, acabo de tomar su respuesta y la extendí un poco para ayudar a redondear esquinas individuales de manera diferente. Esto podría optimizarse un poco más (algunas de las rectas objective se superponen), pero no mucho.

Sé que este hilo es un poco antiguo, pero es uno de los principales resultados de consultas en Google sobre cómo redondear las esquinas de ImageViews en Android.

 /** * Use this method to scale a bitmap and give it specific rounded corners. * @param context Context object used to ascertain display density. * @param bitmap The original bitmap that will be scaled and have rounded corners applied to it. * @param upperLeft Corner radius for upper left. * @param upperRight Corner radius for upper right. * @param lowerRight Corner radius for lower right. * @param lowerLeft Corner radius for lower left. * @param endWidth Width to which to scale original bitmap. * @param endHeight Height to which to scale original bitmap. * @return Scaled bitmap with rounded corners. */ public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft, float upperRight, float lowerRight, float lowerLeft, int endWidth, int endHeight) { float densityMultiplier = context.getResources().getDisplayMetrics().density; // scale incoming bitmap to appropriate px size given arguments and display dpi bitmap = Bitmap.createScaledBitmap(bitmap, Math.round(endWidth * densityMultiplier), Math.round(endHeight * densityMultiplier), true); // create empty bitmap for drawing Bitmap output = Bitmap.createBitmap( Math.round(endWidth * densityMultiplier), Math.round(endHeight * densityMultiplier), Config.ARGB_8888); // get canvas for empty bitmap Canvas canvas = new Canvas(output); int width = canvas.getWidth(); int height = canvas.getHeight(); // scale the rounded corners appropriately given dpi upperLeft *= densityMultiplier; upperRight *= densityMultiplier; lowerRight *= densityMultiplier; lowerLeft *= densityMultiplier; Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); // fill the canvas with transparency canvas.drawARGB(0, 0, 0, 0); // draw the rounded corners around the image rect. clockwise, starting in upper left. canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint); canvas.drawCircle(width - upperRight, upperRight, upperRight, paint); canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint); canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint); // fill in all the gaps between circles. clockwise, starting at top. RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2); RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight); RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height); RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft); canvas.drawRect(rectT, paint); canvas.drawRect(rectR, paint); canvas.drawRect(rectB, paint); canvas.drawRect(rectL, paint); // set up the rect for the image Rect imageRect = new Rect(0, 0, width, height); // set up paint object such that it only paints on Color.WHITE paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET)); // draw resized bitmap onto imageRect in canvas, using paint as configured above canvas.drawBitmap(bitmap, imageRect, imageRect, paint); return output; } 

Romain Guy es donde está.

Versión reducida de la siguiente manera.

 Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap(); Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig()); Canvas canvas = new Canvas(bitmapRounded); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)); canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint); imageView.setImageBitmap(bitmapRounded); 

A continuación, se crea un objeto de diseño de rectángulo redondeado que dibuja un rectángulo redondeado alrededor de los objetos secundarios que se colocan en él. También muestra cómo crear vistas y diseños mediante progtwigción sin utilizar los archivos xml de diseño.

 package android.example; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.ViewGroup.LayoutParams; import android.widget.LinearLayout; import android.widget.TextView; public class MessageScreen extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int mainBackgroundColor = Color.parseColor("#2E8B57"); int labelTextColor = Color.parseColor("#FF4500"); int messageBackgroundColor = Color.parseColor("#3300FF"); int messageTextColor = Color.parseColor("#FFFF00"); DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); float density = metrics.density; int minMarginSize = Math.round(density * 8); int paddingSize = minMarginSize * 2; int maxMarginSize = minMarginSize * 4; TextView label = new TextView(this); /* * The LayoutParams are instructions to the Layout that will contain the * View for laying out the View, so you need to use the LayoutParams of * the Layout that will contain the View. */ LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); label.setLayoutParams(labelLayoutParams); label.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); label.setPadding(paddingSize, paddingSize, paddingSize, paddingSize); label.setText(R.string.title); label.setTextColor(labelTextColor); TextView message = new TextView(this); RoundedRectangle.LayoutParams messageLayoutParams = new RoundedRectangle.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); /* * This is one of the calls must made to force a ViewGroup to call its * draw method instead of just calling the draw method of its children. * This tells the RoundedRectangle to put some extra space around the * View. */ messageLayoutParams.setMargins(minMarginSize, paddingSize, minMarginSize, maxMarginSize); message.setLayoutParams(messageLayoutParams); message.setTextSize(TypedValue.COMPLEX_UNIT_SP, paddingSize); message.setText(R.string.message); message.setTextColor(messageTextColor); message.setBackgroundColor(messageBackgroundColor); RoundedRectangle messageContainer = new RoundedRectangle(this); LinearLayout.LayoutParams messageContainerLayoutParams = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); messageContainerLayoutParams.setMargins(paddingSize, 0, paddingSize, 0); messageContainer.setLayoutParams(messageContainerLayoutParams); messageContainer.setOrientation(LinearLayout.VERTICAL); /* * This is one of the calls must made to force a ViewGroup to call its * draw method instead of just calling the draw method of its children. * This tells the RoundedRectangle to color the the exta space that was * put around the View as well as the View. This is exterior color of * the RoundedRectangle. */ messageContainer.setBackgroundColor(mainBackgroundColor); /* * This is one of the calls must made to force a ViewGroup to call its * draw method instead of just calling the draw method of its children. * This is the interior color of the RoundedRectangle. It must be * different than the exterior color of the RoundedRectangle or the * RoundedRectangle will not call its draw method. */ messageContainer.setInteriorColor(messageBackgroundColor); // Add the message to the RoundedRectangle. messageContainer.addView(message); // LinearLayout main = new LinearLayout(this); LinearLayout.LayoutParams mainLayoutParams = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); main.setLayoutParams(mainLayoutParams); main.setOrientation(LinearLayout.VERTICAL); main.setBackgroundColor(mainBackgroundColor); main.addView(label); main.addView(messageContainer); setContentView(main); } } 

La clase para el objeto de disposición de rectángulo redondeado es como se define aquí:

 /** * A LinearLayout that draws a rounded rectangle around the child View that was added to it. */ package android.example; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.widget.LinearLayout; /** * A LinearLayout that has rounded corners instead of square corners. * * @author Danny Remington * * @see LinearLayout * */ public class RoundedRectangle extends LinearLayout { private int mInteriorColor; public RoundedRectangle(Context p_context) { super(p_context); } public RoundedRectangle(Context p_context, AttributeSet attributeSet) { super(p_context, attributeSet); } // Listener for the onDraw event that occurs when the Layout is drawn. protected void onDraw(Canvas canvas) { Rect rect = new Rect(0, 0, getWidth(), getHeight()); RectF rectF = new RectF(rect); DisplayMetrics metrics = new DisplayMetrics(); Activity activity = (Activity) getContext(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); float density = metrics.density; int arcSize = Math.round(density * 10); Paint paint = new Paint(); paint.setColor(mInteriorColor); canvas.drawRoundRect(rectF, arcSize, arcSize, paint); } /** * Set the background color to use inside the RoundedRectangle. * * @param Primitive int - The color inside the rounded rectangle. */ public void setInteriorColor(int interiorColor) { mInteriorColor = interiorColor; } /** * Get the background color used inside the RoundedRectangle. * * @return Primitive int - The color inside the rounded rectangle. */ public int getInteriorColor() { return mInteriorColor; } } 

¿Por qué no hacer clipping en draw ()?

Aquí está mi solución:

  • extender RelativeLayout con recorte
  • poner ImageView (u otras vistas) en el diseño:

código:

 public class RoundRelativeLayout extends RelativeLayout { private final float radius; public RoundRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray attrArray = context.obtainStyledAttributes(attrs, R.styleable.RoundRelativeLayout); radius = attrArray.getDimension( R.styleable.RoundRelativeLayout_radius, 0); } private boolean isPathValid; private final Path path = new Path(); private Path getRoundRectPath() { if (isPathValid) { return path; } path.reset(); int width = getWidth(); int height = getHeight(); RectF bounds = new RectF(0, 0, width, height); path.addRoundRect(bounds, radius, radius, Direction.CCW); isPathValid = true; return path; } @Override protected void dispatchDraw(Canvas canvas) { canvas.clipPath(getRoundRectPath()); super.dispatchDraw(canvas); } @Override public void draw(Canvas canvas) { canvas.clipPath(getRoundRectPath()); super.draw(canvas); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int oldWidth = getMeasuredWidth(); int oldHeight = getMeasuredHeight(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); int newWidth = getMeasuredWidth(); int newHeight = getMeasuredHeight(); if (newWidth != oldWidth || newHeight != oldHeight) { isPathValid = false; } } } 

Thanks a lot to first answer. Here is modified version to convert a rectangular image into a square one (and rounded) and fill color is being passed as parameter.

 public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) { Bitmap inpBitmap = bitmap; int width = 0; int height = 0; width = inpBitmap.getWidth(); height = inpBitmap.getHeight(); if (width <= height) { height = width; } else { width = height; } Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, width, height); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(inpBitmap, rect, rect, paint); return output; } 

Apply a shape to your imageView as below:

       

it may be helpful to you friend.

This pure xml solution was good enough in my case. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

EDITAR

Here’s the answer in a nutshell:

In the /res/drawable folder, create a frame.xml file. In it, we define a simple rectangle with rounded corners and a transparent center.

        

In your layout file you add a LinearLayout that contains a standard ImageView, as well as a nested FrameLayout. The FrameLayout uses padding and the custom drawable to give the illusion of rounded corners.

        

As of recently, there is another way – using Glide’s Generated API . It takes some initial work but then gives you all the power of Glide with the flexibility to do anything because you writhe the actual code so I think it’s a good solution for the long run. Plus, the usage is very simple and neat.

First, setup Glide version 4+:

 implementation 'com.github.bumptech.glide:glide:4.6.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1' 

Then create Glid’s app module class to trigger the annotation processing:

 @GlideModule public final class MyAppGlideModule extends AppGlideModule {} 

Then create the Glide extension which actually does the work. You can customize it to do whatever you want:

 @GlideExtension public class MyGlideExtension { private MyGlideExtension() {} @NonNull @GlideOption public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) { int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT)); return options.transforms(new RoundedCorners(px)); } } 

After adding these files, build your project.

Then use it in your code like this:

 GlideApp.with(this) .load(imageUrl) .roundedCorners(getApplicationContext(), 5) .into(imageView); 

Here is a simple example overriding imageView, you can then also use it in layout designer to preview.

 public class RoundedImageView extends ImageView { public RoundedImageView(Context context) { super(context); } public RoundedImageView(Context context, AttributeSet attrs) { super(context, attrs); } public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public void setImageDrawable(Drawable drawable) { float radius = 0.1f; Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap); rid.setCornerRadius(bitmap.getWidth() * radius); super.setImageDrawable(rid); } 

}

This is for fast solution. Radius is used on all corners and is based of percentage of bitmap width.

I just overrided setImageDrawable and used support v4 method for rounded bitmap drawable.

Uso:

  

Preview with imageView and custom imageView:

enter image description here

Answer for the question that is redirected here: “How to create a circular ImageView in Android?”

 public static Bitmap getRoundBitmap(Bitmap bitmap) { int min = Math.min(bitmap.getWidth(), bitmap.getHeight()); Bitmap bitmapRounded = Bitmap.createBitmap(min, min, bitmap.getConfig()); Canvas canvas = new Canvas(bitmapRounded); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)); canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min/2, min/2, paint); return bitmapRounded; } 

With the help of glide library and RoundedBitmapDrawableFactory class it’s easy to achieve. You may need to create circular placeholder image.

  Glide.with(context) .load(imgUrl) .asBitmap() .placeholder(R.drawable.placeholder) .error(R.drawable.placeholder) .into(new BitmapImageViewTarget(imgProfilePicture) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(), Bitmap.createScaledBitmap(resource, 50, 50, false)); drawable.setCornerRadius(10); //drawable.setCircular(true); imgProfilePicture.setImageDrawable(drawable); } }); 

if your image is on internet the best way is using glide and RoundedBitmapDrawableFactory (from API 21 – but available in support library) like so:

  Glide.with(ctx).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) { @Override protected void setResource(Bitmap res) { RoundedBitmapDrawable bitmapDrawable = RoundedBitmapDrawableFactory.create(ctx.getResources(), res); bitmapDrawable.setCircular(true);//comment this line and uncomment the next line if you dont want it fully cricular //circularBitmapDrawable.setCornerRadius(cornerRadius); imageView.setImageDrawable(bitmapDrawable); } }); 

If you are using Glide Library this would be helpful:

 Glide.with(getApplicationContext()) .load(image_url) .asBitmap() .centerCrop() .into(new BitmapImageViewTarget(imageView) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource); circularBitmapDrawable.setCornerRadius(dpToPx(10)); circularBitmapDrawable.setAntiAlias(true); imageView.setImageDrawable(circularBitmapDrawable); } }); public int dpToPx(int dp) { DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics(); return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)); } 

Kotlin

 import android.graphics.BitmapFactory import android.os.Bundle import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory import kotlinx.android.synthetic.main.activity_main.* val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage) val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap) rounded.cornerRadius = 20f profileImageView.setImageDrawable(rounded) 

To make ImageView Circular we can change cornerRadius with:

 rounded.isCircular = true 

Quite a lot of answers!

I followed this example which a few people have kinda suggested too: http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

However, what I needed was a coloured circle, behind a transparent image. For anyone who is interested in doing the same…

1) Set the FrameLayout to the width and height – in my case the size of the image (50dp).
2) Place the ImageView that has the src = “@drawable/…”, above the ImageView that has the image. Give it an id, in my case I called it iconShape
3) Drawable mask.xml should have a solid colour of #ffffffff 4) If you want to dynamically change the circle colour in your code, do

 ImageView iv2 = (ImageView) v.findViewById(R.id.iconShape); Drawable shape = getResources().getDrawable(R.drawable.mask); shape.setColorFilter(Color.BLUE, Mode.MULTIPLY); iv2.setImageDrawable(shape); 

You can try this library – RoundedImageView

Es:

A fast ImageView that supports rounded corners, ovals, and circles. A full superset of CircleImageView.

I’ve used it in my project, and it is very easy.

Use this to get circular image with border-

  public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) { if (bitmap == null || bitmap.isRecycled()) { return null; } int borderWidth=(int)(bitmap.getWidth()/40); final int width = bitmap.getWidth() + borderWidth; final int height = bitmap.getHeight() + borderWidth; Bitmap canvasBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(shader); Canvas canvas = new Canvas(canvasBitmap); float radius = width > height ? ((float) height) / 2f : ((float) width) / 2f; canvas.drawCircle(width / 2, height / 2, radius, paint); paint.setShader(null); paint.setStyle(Paint.Style.STROKE); paint.setColor(bordercolor); paint.setStrokeWidth(borderWidth); canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2, paint); return canvasBitmap; } 

If you’re looking for a fast but dirty solution you can use this lib by Vincent Mi.

I’m using a custom view that I layout on top of the other ones and that just draws the 4 small inverted corners in the same color as the background.

Ventajas:

  • Does not allocate a bitmap.
  • Works whatever the View you want to apply the rounded corners.
  • Works for all API levels 😉

Código:

 public class RoundedCornersView extends View { private float mRadius; private int mColor = Color.WHITE; private Paint mPaint; private Path mPath; public RoundedCornersView(Context context) { super(context); init(); } public RoundedCornersView(Context context, AttributeSet attrs) { super(context, attrs); init(); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.RoundedCornersView, 0, 0); try { setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0)); setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE)); } finally { a.recycle(); } } private void init() { setColor(mColor); setRadius(mRadius); } private void setColor(int color) { mColor = color; mPaint = new Paint(); mPaint.setColor(mColor); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); invalidate(); } private void setRadius(float radius) { mRadius = radius; RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius); mPath = new Path(); mPath.moveTo(0,0); mPath.lineTo(0, mRadius); mPath.arcTo(r, 180, 90); mPath.lineTo(0,0); invalidate(); } @Override protected void onDraw(Canvas canvas) { /*This just draws 4 little inverted corners */ int w = getWidth(); int h = getHeight(); canvas.drawPath(mPath, mPaint); canvas.save(); canvas.translate(w, 0); canvas.rotate(90); canvas.drawPath(mPath, mPaint); canvas.restre(); canvas.save(); canvas.translate(w, h); canvas.rotate(180); canvas.drawPath(mPath, mPaint); canvas.restre(); canvas.translate(0, h); canvas.rotate(270); canvas.drawPath(mPath, mPaint); } }