¿Cómo hacer un ImageView con esquinas redondeadas?

573

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 mapa de bits para que sean rectángulos redondeados) en ImageView?

Miguel
fuente
Esto podría ser útil stackoverflow.com/questions/26850780/…
Mangesh
Oculto debajo de las respuestas más antiguas y complicadas es lo que creo que debería ser la respuesta aceptada ahora: RoundedBitmapDrawable , agregado en v4 Support Library revisión 21.
Jonik
Puede hacerlo de la manera más fácil simplemente usando CardView con un ImageView adentro: mire el ejemplo aquí stackoverflow.com/a/41479670/4516797
Taras Vovkovych
Esta biblioteca es muy útil.
grrigore
Comprobar esto ahora tenemos ShapeableImageViewque hacer circular o redondeada imageView stackoverflow.com/a/61086632/7666442
Nilesh Rathod

Respuestas:

545

Esto es bastante tarde en la 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 de maravilla. Lo utilicé como ayudante dentro de una clase ImageHelper y lo extendí solo un poco para pasar la cantidad de plumaje que necesito para una imagen determinada.

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!

George Walters II
fuente
44
No funciona para todos los dispositivos. ¿Necesito cambiar en alguna parte?
Spring Breaker
77
Se tarda casi 0,03 segundos en hacer eso para una imagen de 200 * 200, por lo que creo que esa no es la mejor solución.
Jacky
2
Solo redondea las esquinas superior izquierda y superior derecha. Por qué ?
Prateek
1
¡La solución @ vinc3m1 aquí github.com/makeramen/RoundedImageView funciona realmente bien! también vea su respuesta ( stackoverflow.com/a/15032283/2048266 )
nommer
16
No funciona bien al intentar establecer el tipo de escala de la vista de imagen, solo fitXY funciona, centerCrop y otros muestran resultados impredecibles, ¿alguien aquí tiene los mismos problemas?
Shivansh
211

Si bien la respuesta anterior funciona, Romain Guy (un desarrollador principal de Android) muestra un mejor método en su blog que usa menos memoria al usar un sombreador que no crea una copia del mapa de bits. 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 mapa de bits, que usa mucha memoria con imágenes grandes [frente a la mayoría de las otras respuestas aquí]
  • admite antialimentación [vs método clipPath]
  • admite alfa [vs xfermode + método porterduff]
  • admite aceleración de hardware [vs método clipPath]
  • solo dibuja una vez en el lienzo [frente a los métodos xfermode y clippath]

He creado un RoundedImageView basado en este código que envuelve esta lógica en un ImageView y agrega el ScaleTypesoporte adecuado y un borde redondeado opcional.

vinc3m1
fuente
en su / example / res / layout / rounded_item.xml ¿por qué especifica una imagen src cuando todas sus fuentes están codificadas? Buena demostración, simplemente exagerada.
Alguien en alguna parte
su muestra tiene un problema grave de falta de memoria, al igual que la muestra original de Romain Guy. Todavía no sé qué lo causa, pero al igual que su código, es algo realmente difícil de encontrar. Si no puede ver un bloqueo de la aplicación debido a OOM, puede rotar la aplicación varias veces hasta que ocurra (depende de su dispositivo, ROM, etc.). He informado sobre esto en el pasado aquí: stackoverflow.com/questions/14109187/…
desarrollador de Android
1
Nadie más está informando el problema de falta de memoria, por lo que debe ser algo que está haciendo fuera del código que es incorrecto. El ejemplo contiene correctamente un conjunto limitado de mapas de bits en el adaptador sin volver a crearlos cada vez que se dibuja una vista. El ejemplo que se muestra aquí es un fragmento del método draw () en Drawable, que utiliza la referencia al mapa de bits original que contiene y funciona correctamente. Se no pretende cambiar el mapa de bits original, pero sólo hacerla con las esquinas redondeadas. El recorte central también funciona bien en el ejemplo.
vinc3m1
1
Si puede proporcionar capturas de pantalla o dispositivos donde no funciona, o incluso llegar a ofrecer una solicitud de reparación y extracción, sería más productivo. He probado rotar varias veces en mis dispositivos y la memoria sigue siendo la misma.
vinc3m1
11
Tenga en cuenta que no funcionará si el tamaño de la imagen es superior a 2048 píxeles. El sombreador no admite una textura que sea más grande que eso.
Gábor
209

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

  <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:cardCornerRadius="8dp"
            android:layout_margin="5dp"
            android:elevation="10dp">

            <ImageView
                android:id="@+id/roundedImageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/image"
                android:background="@color/white"
                android:scaleType="centerCrop"
                />
        </android.support.v7.widget.CardView>

ingrese la descripción de la imagen aquí

Taras Vovkovych
fuente
55
Parece una buena solución. Pero no recorta imágenes en pre-Lollipops.
Nikolai
1
¿Qué sucede si solo queremos un radio en las esquinas superior izquierda y superior derecha y no en todas las esquinas?
Pratik Singhal
3
Manera muy simple e inteligente de aplicar borde de curva en cualquier vista.
AMI CHARADAVA
1
Buena solución, pero la elevación solo se admite en el nivel 21 de la API y superior
Saad Bilal
1
Para deshabilitar la elevación de la tarjeta, use la aplicación: cardElevation = "0dp" (no android: elevación)
Johnny Five
150

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

Solo haz esto:

  • Crea una forma redondeada dibujable, algo como esto:

res / drawable / round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>
  • Establezca el dibujable como fondo de su ImageView: android:background="@drawable/round_outline"
  • De acuerdo con esta documentación , todo lo que necesita hacer es agregarandroid:clipToOutline="true"

Desafortunadamente, hay un error y ese atributo XML no se reconoce. Afortunadamente, todavía podemos configurar el recorte en Java:

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

Así es como se verá:

ingrese la descripción de la imagen aquí

Nota:

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

Nota especial sobre ImageViews

setClipToOutline()solo funciona cuando el fondo de la Vista está configurado en una forma dibujable. Si existe esta forma de fondo, Ver trata el contorno de la forma como los bordes con fines de recorte y sombreado.

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

  • Cree un diseño y establezca su fondo en su forma dibujable
  • Envuelva ese diseño alrededor de su ImageView (sin relleno)
  • El ImageView (incluyendo cualquier otra cosa en el diseño) ahora se mostrará con forma de diseño redondeado.
hambre
fuente
10
Error: (x) No se encontró un identificador de recurso para el atributo 'clipToOutline' en el paquete 'android'
Anu Martin
77
En cambio android:clipToOutline, uno debe usar android:outlineProvider="background".
WindRider
2
Otra razón por la que "amo" tanto a Google es que este error es casi de mi edad y aún reside en su pequeño mundo. Google parece no estar dando ninguna * cr * ap al respecto))
Farid
1
Parece que no tengo éxito con este método cuando solo establezco topleft y topRight corner en la forma de fondo en redondeado.
Peterdk
@AnuMartin este es un problema conocido - issuetracker.google.com/issues/37036728
Vadim Kotov
132

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 srcun objetivo ImageView, se vería así:

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
tyczj
fuente
3
Muchas gracias, aquí está el siguiente paso: stackoverflow.com/questions/24878740/…
David d C e Freitas
en realidad no es android.support.v4.graphics.drawable.RoundedBitmapDrawableFactoryasí que v4también es compatible con ella.
deadfish
2
@deadfish sí, está en la v4biblioteca de soporte, pero no hasta REVISION 21la biblioteca de soporte
tyczj
3
Esta es una solución simple y actualizada. Requiere la menor cantidad de código y tiene una gran extensibilidad. Puede trabajar con imágenes de archivos locales, dibujables en caché o incluso con NetworkImageView de Volley. Estoy totalmente de acuerdo en que esta debería ser la respuesta aceptada hoy en día, como señaló @Jonik.
katie
2
Desafortunadamente no funciona con scaleType centerCrop(biblioteca de soporte v25.3.1)
rocknow
67

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:

<com.mypackage.RoundRectCornerImageView
     android:id="@+id/imageView"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/image"
     android:scaleType="fitXY" />

Salida:

ingrese la descripción de la imagen aquí

Espero que esto te ayude.

Hiren Patel
fuente
esto hace que la imagen se vea borrosa
Amit Hooda
2
funciona incluso con android: scaleType = "centerCrop", simple, no crea un nuevo mapa de bits. ¡Gracias!
ernazm
1
@Hiren Esta solución funciona bien para ImageView con una imagen de fondo. Pero no funciona para ImageViews que solo tiene color de fondo y no tiene imagen. ¿Puedes decirme por qué sucede esto?
user2991413
Canvas.clipPath()puede causar java.lang.UnsupportedOperationExceptionen algunos casos. Ver stackoverflow.com/questions/13248904/…
Artyom el
1
Esta solución solo funciona para el conjunto de imágenes con android:background, pero no android:src.
CoolMind
65

Una solución rápida xml -

<android.support.v7.widget.CardView
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:cardElevation="0dp"
            app:cardCornerRadius="4dp">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rounded_user_image"
        android:scaleType="fitXY"/>

</android.support.v7.widget.CardView>

Puede establecer su ancho, altura y radio deseados en CardView y scaleType en ImageView.

Con AndroidX, use <androidx.cardview.widget.CardView>

Chirag Mittal
fuente
44
este enfoque funcionó en mi caso con androidx.cardview.widget.CardView
Ivan
77
¿No está seguro de por qué esto no tiene más votos a favor? En mi opinión, la mejor solución sin bibliotecas y toneladas de código de mierda (aunque en mi caso usé el escalado centerCrop).
ThemBones
1
Todavía no hay muchos votos a favor, porque es una nueva respuesta. ¡Pero puse mi +1 para subirlo pronto! ¡Gracias!
Micer
sin embargo, funciona, pero aquí la imagen se estirará debido a scaleType="fitXY"que no se ve bien @ThemBones
MAGO
@WIZARD es por eso que mencioné que puedes configurar tu scaleType deseado en ImageView
Chirag Mittal
57

Descubrí que ambos métodos fueron muy útiles para encontrar una solución de trabajo. Aquí está mi versión compuesta, que es independiente de píxeles y le permite tener algunas esquinas cuadradas con el resto de las esquinas que tienen 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, anulé ImageView para poner esto para poder definirlo en xml. Es posible que desee agregar algo de la lógica que hace la súper llamada aquí, pero lo 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!

Caspar Harmer
fuente
44
bastante impresionante, especialmente extendiendo ImageView
Alguien en algún lugar
2
Una manera simple de mantener la lógica de ImageView # onDraw () es establecer el mapa de bits de la esquina redondeada en el dibujable de ImageView, y dejar el super.onDraw () para dibujar el mapa de bits. He creado una clase RoundedCornerImageView , y su ejemplo de uso está aquí . Tenga en cuenta que el getRoundedCornerBitmap () que he usado no es independiente de píxeles.
umbalaconmeogia
Gracias por RoundedCornerImageView. Lo usé pero lo modifiqué para que sea independiente de la densidad de píxeles.
PacificSky
El código fuente de RoundedCornerImageView de umba está aquí: code.google.com/p/android-batsg/source/browse/trunk/…
Someone Somewhere
@Caspar Harmer funciona bien solo 1 edición ... hay cuatro condiciones ... solo cámbielas como si configuro verdadero, verdadero, falso, falso establecerá la esquina inferior en lugar de la esquina superior ... de lo contrario, el código funciona bien.so squareTL y squareTR son condiciones para squareBL y squareBR respectivamente ... y vica-versa.
TheFlash
48

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 PicassoBiblioteca 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 de Transformación Redondeada aquí

shailesh
fuente
1
No se muestra la imagen
Amit Thaper
3
La Biblioteca Picasso es buena y muy fácil de implementar, muchas gracias +1
Hitesh
3
Sin embargo, la biblioteca Picasso parece no transformar la imagen de "marcador de posición" y de "error", por lo que si su imagen no se carga (error) o tarda un tiempo en cargarse inicialmente (marcador de posición) no mostrará la imagen como una imagen redondeada. github.com/square/picasso/issues/337
Pelpotronic
Esta biblioteca proporciona otras transformaciones útiles de picasso, que también contiene una transformación RoundedCorners: github.com/wasabeef/picasso-transformations
Massimo
No funciona con recortar imágenes en Univ. Cargador de imágenes.
Yar
26

Como todas las respuestas me parecieron demasiado complicadas solo para las esquinas redondeadas, pensé y encontré otra solución que creo que vale la pena compartir, solo con XML en caso de que tenga algo de espacio alrededor de la imagen:

Cree una forma bordeada con contenido transparente como este:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners 
        android:radius="30dp" />
    <stroke 
        android:color="#ffffffff"
        android:width="10dp" />
</shape> 

Luego, en un 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 mayor en tamaño por la cantidad del ancho del borde. Tenga cuidado de tomar un radio de esquina más grande ya que el radio exterior está definido, pero el radio interior es lo que cubre su imagen.

Espero que ayude a alguien también.

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageToShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imgCorners"
        android:layout_alignLeft="@+id/imgCorners"
        android:layout_alignRight="@+id/imgCorners"
        android:layout_alignTop="@+id/imgCorners"
        android:background="#ffffff"
        android:contentDescription="@string/desc"
        android:padding="5dp"
        android:scaleType="centerCrop" />

    <ImageView
        android:id="@+id/imgCorners"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/desc"
        android:src="@drawable/corners_white" />

</RelativeLayout>
cristiano
fuente
¿puede elaborar más sobre esto con más código, especialmente lo que se está haciendo con la segunda vista de imagen y dónde se aplica el xml de "forma de borde" (como src o como fondo?) varias preguntas aquí. Quiero que me guste esta solución, ya que me permitirá controlar las cuatro esquinas de forma independiente
CQM
1
Aunque parece ser una respuesta simple, desafortunadamente agrega un margen alrededor de la vista de imagen "enmascarada", que es un efecto secundario indeseable.
Abdalrahman Shatou
sí, pero lo mismo funciona con un ImageView basado en un PNG-Drawable con esquinas redondeadas y fondo transparente o un 9-Patch-Drawable si tiene un aspecto indefinido.
Christian
Estoy haciendo lo mismo, y está funcionando; ¿solo está dispuesto a saber si no creará ningún problema con la orientación y el diferente tamaño del teléfono?
Abierto y gratuito el
Si mantiene las dimensiones relativas entre sí, esto no debería crear un problema.
Christian
22

Comenzando con la versión 1.2.0-alpha03de la Biblioteca de Componentes de Materiales, está la nueva ShapeableImageView.

Puedes usar algo como:

  <com.google.android.material.imageview.ShapeableImageView
      ...
      app:shapeAppearanceOverlay="@style/roundedImageView"
      app:srcCompat="@drawable/ic_image" />

con:

  <style name="roundedImageView" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">8dp</item>
  </style>

O programáticamente:

float radius = getResources().getDimension(R.dimen.default_corner_radius);
imageView.setShapeAppearanceModel(imageView.getShapeAppearanceModel()
    .toBuilder()
    .setAllCorners(CornerFamily.ROUNDED,radius)
    .build());

ingrese la descripción de la imagen aquí

Gabriele Mariotti
fuente
Si la imagen tiene color de fondo, esto produce actualmente que el color de fondo aparezca debajo de las esquinas redondeadas. Esto también ignora la propiedad scaleType en la imagen.
inokey
14

Mi implementación de ImageView con widget de esquinas redondeadas, que (abajo || arriba) dimensiona la imagen a las dimensiones requeridas. Utiliza el código de 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);

    }

}
Damjan
fuente
12
¿De dónde viene ImageUtilities?
JasonWyatt
1
@JasonWyatt ve la publicación de sorrodos a continuación
Damjan
12

Recientemente, hay otra forma: usar la API generada de Glide . Requiere un poco de trabajo inicial, pero luego le brinda todo el poder de Glide con la flexibilidad de hacer cualquier cosa porque redacta el código real, así que creo que es una buena solución a largo plazo. Además, el uso es muy simple y ordenado.

Primero, configure Glide versión 4+:

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

Luego cree la clase de módulo de aplicación de Glid para activar el procesamiento de anotaciones:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

Luego cree la extensión Glide que realmente hace el trabajo. Puedes personalizarlo para hacer lo que quieras:

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

Después de agregar estos archivos, cree su proyecto.

Luego úsalo en tu código así:

GlideApp.with(this)
        .load(imageUrl)
        .roundedCorners(getApplicationContext(), 5)
        .into(imageView);
Sir Codesalot
fuente
No se olvide de agregar un espacio entre RequestOptionsy optionsen los params
StevenTB
Hecho. Gracias por el aporte.
Sir Codesalot
.itatedCorners no vienen ¿necesitamos configurar algo más? Incluso después del proyecto de reconstrucción
Dr. anDRO
Esto funcionó para mí, gracias. Encontré más simple evitar usar la @GlideExtensionclase anotada y simplemente fui con .transform(new RoundedCorners(px))where pxis the same ( int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));).
Michael Osofsky
10

Hay una biblioteca genial que te permite dar forma a las vistas de imágenes.

Aquí hay un ejemplo:

<com.github.siyamed.shapeimageview.mask.PorterShapeImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:siShape="@drawable/shape_rounded_rectangle"
    android:src="@drawable/neo"
    app:siSquare="true"/>

Definición de forma:

<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
    <corners
        android:topLeftRadius="18dp"
        android:topRightRadius="18dp"
        android:bottomLeftRadius="18dp"
        android:bottomRightRadius="18dp" />
    <solid android:color="@color/black" />
</shape>

Resultado:

resultado

Grrigore
fuente
1
Esto es genial y hace mucho más, como si pudieras agregar un borde y usar cualquier forma
Adam Kis
8

Aquí hay un ejemplo simple que reemplaza imageView, luego también puede usarlo en el diseñador de diseño para obtener una vista previa.

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

Esto es para una solución rápida. El radio se usa en todas las esquinas y se basa en el porcentaje del ancho del mapa de bits.

Simplemente anulé setImageDrawabley utilicé el método de soporte v4 para el mapa de bits redondeado dibujable.

Uso:

<com.example.widgets.RoundedImageView
        android:layout_width="39dp"
        android:layout_height="39dp"
        android:src="@drawable/your_drawable" />

Vista previa con imageView e imageView personalizado:

ingrese la descripción de la imagen aquí

pez muerto
fuente
Esto está funcionando en todas las situaciones, gracias. Salvaste mi día.
Mehul Solanki
7

Debes extender ImageViewy dibujar tu propio rectángulo redondeado.

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

[editar] Superponga el marco para optar por la imagen original, usando un FrameLayoutpor ejemplo. El primer elemento de la FrameLayoutserá la imagen que desea mostrar redondeada. Luego agregue otro ImageViewcon el marco. El segundo ImageViewse mostrará en la parte superior del original ImageViewy, por lo tanto, Android dibujará su contenido sobre el original ImageView.

MrSnowflake
fuente
Gracias. Pero solo hay un método setDrawable para ImageView, ¿cómo puedo establecerDrawable de ImageView en el contenido de mi imagen y luego superponer un marco redondeado en la parte superior de ImageView?
michael
Lo siento, no estaba claro. Me refería a superponer en el diseño: por lo tanto (es decir, usar un FrameLayoutponer un ImageViewy agregar otro ImageViewcon el marco redondeado. De esa manera, el primero ImageViewmostrará la imagen seleccionada y el segundo ImageFramemostrará el marco redondeado.
MrSnowflake
Correcto: con FrameLayout puede superponer una imagen / vista con otra. También puede hacer uso de la etiqueta android: primer plano de FrameLayout.
Richard Le Mesurier
7

Romain Guy está 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);
Alex
fuente
lamentablemente, a pesar de que funciona, pero al igual que el resto de las soluciones aquí, crea un nuevo mapa de bits en lugar de usar el actual.
Desarrollador de Android
realmente no. bitmapRounded se usaría una y otra vez. Si tuvo acceso al lienzo dibujable, puede utilizar el método de dibujo directamente en lugar de generar un nuevo mapa de bits.
Alex
¿Cómo haces eso? supongamos que no uso ningún dibujo especial y solo manejo un único mapa de bits y uso setImageBitmap al final del proceso. ¿Cómo podría lograr tal cosa?
Desarrollador de Android
ambos no cambian el mapa de bits, sino que lo envuelven con un dibujo personalizado y una vista de imagen personalizada. Esto no es lo que pregunté. Le pregunté cómo cambiar el mapa de bits en sí.
Desarrollador de Android
7

Esta solución xml pura fue lo suficientemente buena en mi caso. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

EDITAR

Aquí está la respuesta en pocas palabras:

En la carpeta / res / drawable, cree un archivo frame.xml. En él, definimos un rectángulo simple con esquinas redondeadas y un centro transparente .

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
     <solid android:color="#00ffffff" />
     <padding android:left="6dp"
        android:top="6dp"
        android:right="6dp"
        android:bottom="6dp" />
     <corners android:radius="12dp" />
     <stroke android:width="6dp" android:color="#ffffffff" />
</shape>

En su archivo de diseño, agrega un LinearLayout que contiene un ImageView estándar, así como un FrameLayout anidado. FrameLayout utiliza relleno y el dibujo personalizado para dar la ilusión de esquinas redondeadas.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:gravity="center" 
    android:background="#ffffffff">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="6dp"
        android:src="@drawable/tr"/>

    <FrameLayout 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="6dp"
            android:src="@drawable/tr"/>

        <ImageView 
             android:src="@drawable/frame"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />

    </FrameLayout>

</LinearLayout>
j7nn7k
fuente
buena idea, lo usé para mostrar una esquina de ImageView no uniforme
Gal Rom
6

Apoyando a George Walters II arriba, tomé 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 referencias objetivo se superponen), pero no mucho.

Sé que este hilo es un poco viejo, pero es uno de los mejores resultados para las 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;
}
sorrodos
fuente
+1 para agregar el multiplicador de densidad y agregar soporte para redondear esquinas individualmente. De hecho, utilicé la solución en la parte superior, ya que su solución no funcionó del todo, ¡pero fue muy útil! Vea mi solución compuesta a continuación:
Caspar Harmer
6

Aplique una forma a su imageViewcomo a continuación:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="#faf5e6" />
    <stroke
        android:width="1dp"
        android:color="#808080" />
    <corners android:radius="15dp" />
    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />
</shape>

Puede ser útil para tu amigo.

jigar
fuente
6

¿Por qué no hacer clipping draw()?

Aquí está mi solución:

  • Extienda RelativeLayout con recorte
  • Ponga 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;
        }
    }

}
Fishautumn
fuente
1
Me gusta este enfoque. Lo usé para crear mi propio RoundImageView. Gracias por esto.
Pascal
Esto no funciona con la aceleración acelerada activada, ¿correcto? No vi una solución fácil ...
secureboot
¿Puede mostrar cómo hacerlo, al tener el resultado como dibujable, tener la capacidad de agregar un contorno (trazo AKA) alrededor del contenido y también tener la capacidad de hacer que algunas de las esquinas se redondeen?
Desarrollador de Android
5

Lo siguiente 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 programación sin usar 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 diseño RoundedRectangle 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;
 }

}
Danny Remington - OMS
fuente
5

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)

Para hacer ImageViewCircular podemos cambiar cornerRadiuscon:

rounded.isCircular = true
Vahid
fuente
4

Muchas gracias por la primera respuesta. Aquí hay una versión modificada para convertir una imagen rectangular en una cuadrada (y redondeada) y el color de relleno se pasa como parámetro.

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;
}
mkm
fuente
4

Si está utilizando Glide Library, esto sería útil:

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));
}
Anirudh
fuente
Si usa Glide versión 4 y superior, use --- RequestOptions requestOptions = new RequestOptions (); requestOptions = requestOptions.transforms (new CenterCrop (), new RoundedCorners (16)); Glide.with (itemView.getContext ()) .load (item.getImage ()) .apply (requestOptions) .into (mProgramThumbnail);
B.shruti
3

si su imagen está en Internet, la mejor manera es usar glide y RoundedBitmapDrawableFactory(desde API 21, pero disponible en la biblioteca de soporte) de esta manera:

 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);
    }
});
Amir Ziarati
fuente
Esta es una API elegante, sin embargo, parece que falta .centerInside, por lo tanto, quizás sea mejor usar xml para definir dichos parámetros
carl
Esto también es útil cuando la imagen está en recursos y necesita usarlacenterCrop
Artyom
3

puede usar solo ImageViewen su diseño y usar glide, puede aplicar esquinas redondeadas con este método.

primero en tu gradle escribe,

compile 'com.github.bumptech.glide:glide:3.7.0'

para imagen con esquinas redondeadas,

public void loadImageWithCorners(String url, ImageView view) {
    Glide.with(context)
            .load(url)
            .asBitmap()
            .centerCrop()
            .placeholder(R.color.gray)
            .error(R.color.gray)
            .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .into(new BitmapImageViewTarget(view) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable =
                            RoundedBitmapDrawableFactory.create(context.getResources(), resource);
                    circularBitmapDrawable.setCornerRadius(32.0f); // radius for corners
                    view.setImageDrawable(circularBitmapDrawable);
                }
            });
}

método de llamada:

loadImageWithCorners("your url","your imageview");
Patel profundo
fuente
Esto agregará una biblioteca para cargar imágenes a través de una solicitud HTTP, que no es relevante para la pregunta.
creativecreatorormaybenot
¿Qué biblioteca se cargará? Para la carga de imágenes, puede usar glide y el fragmento basado únicamente en métodos y clases de glide. No es necesario agregar ninguna otra biblioteca
Deep Patel el
Glide es una biblioteca principalmente para cargar imágenes a través de HTTP, pero OP quería saber cómo redondear las esquinas de un ImageView.
creativecreatorormaybenot
2

Responda a la pregunta que se redirige aquí: "¿Cómo crear un ImageView circular en 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;
}
Andrey
fuente
2

Con la ayuda de la biblioteca glide y la clase RoundedBitmapDrawableFactory es fácil de lograr. Es posible que deba crear una imagen de marcador de posición circular.

    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);
            }
        });
Chitrang
fuente
2

Para los que usan Glide y Kotlin, puedes lograrlo extendiendo RequestBuilder

fun <T> GlideRequest<T>.roundCorners(cornerRadius: Int) =
    apply(RequestOptions().transform(RoundedCorners(cornerRadius)))

y usar como;

 GlideApp.with(context)
            .load(url)
            .roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
            .into(imgView)
dgngulcan
fuente
.itatedCorners no vienen ¿necesitamos configurar algo más?
Dr. anDRO
¿Agregaste la función de extensión roundCornerscomo arriba? @ Dr.aNdRO
dgngulcan
¡Por favor proporcione el ejemplo apropiado! ¡Esta respuesta es confusa!
Junia Montana