¿Cómo redondear una imagen con la biblioteca Glide?


197

Entonces, ¿alguien sabe cómo mostrar una imagen con esquinas redondeadas con Glide? Estoy cargando una imagen con Glide, pero no sé cómo pasar parámetros redondeados a esta biblioteca.

Necesito mostrar la imagen como el siguiente ejemplo:

ingrese la descripción de la imagen aquí


2
He usado github.com/hdodenhof/CircleImageView para ver la imagen
ronded

1
Sé cómo usar Glide lib con CircleImageView, pero busco posibles formas de hacerlo solo con Glide lib. ¿Tiene algún método en Glide lib para hacer esto o no es compatible?
mr.boyfox

Respuestas:


486

Glide V4:

    Glide.with(context)
        .load(url)
        .circleCrop()
        .into(imageView);

Glide V3:

Puede usar RoundedBitmapDrawablepara imágenes circulares con Glide. No se requiere ImageView personalizado.

 Glide.with(context).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable =
                    RoundedBitmapDrawableFactory.create(context.getResources(), resource);
            circularBitmapDrawable.setCircular(true);
            imageView.setImageDrawable(circularBitmapDrawable);
        }
    });

66
Sin embargo, esto no crea un borde.
ZakTaccardi

1
@ jimmy0251 No, no puedes. Los elementos dibujables de planeo no son BitmapDrawables. Son dibujos de transición y de deslizamiento que se desvanecen del marcador de posición a la imagen real. RoundedBitmapDrawable no puede manejar eso.
Greg Ennis

77
Establecer fondo con forma dibujable oval. y dar relleno a la vista de imagen para crear borde.
Lalit Jadav

2
Si tiene algún problema, compruebe la siguiente solución de Roman Samoylenko que funciona.
Pabel

1
En lugar de .centerCrop()que probablemente quieras decir.circleCrop()
Thanasis Kapelonis

66

Revise esta publicación, deslizarse vs picasso ...
Editar : la publicación vinculada no señala una diferencia importante en las bibliotecas. Glide hace el reciclaje automáticamente. Vea el comentario de TWiStErRob para más información.

Glide.with(this).load(URL).transform(new CircleTransform(context)).into(imageView);

public static class CircleTransform extends BitmapTransformation {
    public CircleTransform(Context context) {
        super(context);
    }

    @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        // TODO this could be acquired from the pool too
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override public String getId() {
        return getClass().getName();
    }
} 

suena interesante. ¿Funciona bien con el esquema de API 21?
Teovald

hmm, podría usar esto entonces. Sin embargo, intentaré simplemente usar una vista personalizada, me gustaría no tener que crear un segundo mapa de bits :). Además, siempre debe usar el grupo de mapas de bits para intentar obtener un mapa de bits desde allí :)
Teovald

¡Tenga cuidado de usar public String getId()la forma en que se muestra en el código, ya que devuelve la misma identificación para todas las imágenes y, por lo tanto, podría ocurrir que el deslizamiento establezca imágenes redondeadas antiguas mientras que sin transformaciones establecerá la imagen correcta! No sé cómo funciona el deslizamiento, pero parece que almacena transformaciones de imágenes (para evitar cálculos rígidos, supongo). Y la identificación se usa como la identificación de la imagen transformada. Agregué una url de imagen al constructor e hice que el método mencionado devolviera la identificación resultante como:this.id = String.format("%s:%s",this.getClass().getSimpleName(),id);
Stan

2
El único requisito de Stan para los identificadores de transformación es que son únicos entre todas las transformaciones, por lo que el uso aquí es correcto. Las claves de caché incluirán tanto la identificación de origen como la identificación de transformación, por lo que la identificación de transformación es una combinación en lugar de un reemplazo. Ver github.com/bumptech/glide/wiki/…
Sam Judd

44
¿Hay alguna manera de aplicar la transformación al marcador de posición?
Sinigami

45

La forma más fácil (requiere Glide 4.xx)

Glide.with(context).load(uri).apply(RequestOptions().circleCrop()).into(imageView)

esto ni siquiera compila ... RequestOptions ()?
Rafael Lima

3
@RafaelLima Está escrito en Kotlin.
Roman Samoylenko

1
Aviso, eso .apply()va después .load().
Johnny Five

es RequestOptions.circleCropTransform (), no RequestOptions ().
Sonrisas

necesitas escribir Glide.with (context) .load (uri) .apply (circleCrop ()). en (imageView) mira la función apply.
Jaspal

25

Intenta de esta manera

código

Glide.with(this)
    .load(R.drawable.thumbnail)
    .bitmapTransform(new CropCircleTransformation(this))
    .into(mProfile);

XML

<ImageView
  android:id="@+id/img_profile"
  android:layout_width="76dp"
  android:layout_height="76dp"
  android:background="@drawable/all_circle_white_bg"
  android:padding="1dp"/>

all_circle_white_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <shape android:shape="oval">
      <solid android:color="@android:color/white"/>
  </shape>
  </item>
</selector>

9

es muy simple, he visto la biblioteca Glide, su muy buena biblioteca y base de ensayos en la biblioteca de Google volley

use esta biblioteca para una vista de imagen redondeada

https://github.com/hdodenhof/CircleImageView

ahora

// Para una vista simple:

 @Override
 public void onCreate(Bundle savedInstanceState) {
  ...

  CircleImageView civProfilePic = (CircleImageView)findViewById(R.id.ivProfile);
  Glide.load("http://goo.gl/h8qOq7").into(civProfilePic);
}

// Para una lista:

@Override
public View getView(int position, View recycled, ViewGroup container) {
final ImageView myImageView;
 if (recycled == null) {
    myImageView = (CircleImageView) inflater.inflate(R.layout.my_image_view,
            container, false);
} else {
    myImageView = (CircleImageView) recycled;
}

String url = myUrls.get(position);

Glide.load(url)
    .centerCrop()
    .placeholder(R.drawable.loading_spinner)
    .animate(R.anim.fade_in)
    .into(myImageView);

  return myImageView;
}

y en XML

<de.hdodenhof.circleimageview.CircleImageView
   android:id="@+id/ivProfile
   android:layout_width="160dp"
   android:layout_height="160dp"
   android:layout_centerInParent="true"
   android:src="@drawable/hugh"
   app:border_width="2dp"
   app:border_color="@color/dark" />

2
Como se mencionó en el comentario de respuesta anterior de esta manera tampoco funciona bien. Al menos para 'de.hdodenhof: circleimageview: 1.2.2' + 'com.github.bumptech.glide: glide: 3.5.2'. Comprobado y doble comprobado. También el mismo problema con glide 3.4. + Y circleimageview 1.2.1
Stan

+1 para el .centerCrop (). Me funcionó con DiamondImageView plus .asBitmap ().
felippe

1
Requiere llamar a .dontAnimate () en glide, lo cual no es aceptable
Greg Ennis

+1 Pero también tenga en cuenta que Carga de imágenes de Internet con Glide
hedgehog

9

Las otras soluciones no funcionaron para mí. Descubrí que todos tienen inconvenientes significativos:

  • Las soluciones que usan transformaciones de deslizamiento no funcionan con marcadores de posición
  • Las soluciones que utilizan vistas de imágenes redondeadas no funcionan con animaciones (es decir, fundido cruzado)
  • Las soluciones que utilizan un método genérico de un padre que recorta a sus hijos (es decir, la respuesta aceptada aquí ) no funcionan bien con deslizamiento

Es realmente interesante que después de hurgar en esto encontré la página de la biblioteca de Fresco sobre esquinas redondeadas y círculos en los que enumeran básicamente las mismas limitaciones y concluyen con la declaración:

no hay una solución realmente buena para redondear esquinas en Android y uno tiene que elegir entre las compensaciones antes mencionadas

Increíble que en este momento todavía no tenemos una solución real. Tengo una solución alternativa basada en el enlace que puse arriba. El inconveniente de este enfoque es que supone que su fondo es de color sólido (las esquinas no son realmente transparentes). Lo usarías así:

<RoundedCornerLayout ...>
    <ImageView ...>
</RoundedCornerLayout>

La esencia está aquí y el código completo aquí:

public class RoundedCornerLayout extends RelativeLayout {
    private Bitmap maskBitmap;
    private Paint paint;
    private float cornerRadius;

    public RoundedCornerLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        setWillNotDraw(false);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        if (maskBitmap == null) {
            // This corner radius assumes the image width == height and you want it to be circular
            // Otherwise, customize the radius as needed
            cornerRadius = canvas.getWidth() / 2;
            maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
        }

        canvas.drawBitmap(maskBitmap, 0f, 0f, paint);
    }

    private Bitmap createMask(int width, int height) {
        Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mask);

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE); // TODO set your background color as needed

        canvas.drawRect(0, 0, width, height, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);

        return mask;
    }
}

6

Ahora en Glide V4 puedes usar directamente CircleCrop ()

Glide.with(fragment)
  .load(url)
  .circleCrop()
  .into(imageView);

Construido en tipos

  • CenterCrop
  • FitCenter
  • CircleCrop

5

Usa esta transformación, funcionará bien.

public class CircleTransform extends BitmapTransformation {
public CircleTransform(Context context) {
    super(context);
}

@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
    return circleCrop(pool, toTransform);
}

private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
    if (source == null) return null;

    int borderColor = ColorUtils.setAlphaComponent(Color.WHITE, 0xFF);
    int borderRadius = 3;

    int size = Math.min(source.getWidth(), source.getHeight());
    int x = (source.getWidth() - size) / 2;
    int y = (source.getHeight() - size) / 2;

    // TODO this could be acquired from the pool too
    Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
    if (squared != source) {
        source.recycle();
    }

    Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
    if (result == null) {
        result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(result);
    Paint paint = new Paint();
    paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
    paint.setAntiAlias(true);
    float r = size / 2f;
    canvas.drawCircle(r, r, r, paint);

    // Prepare the background
    Paint paintBg = new Paint();
    paintBg.setColor(borderColor);
    paintBg.setAntiAlias(true);

    // Draw the background circle
    canvas.drawCircle(r, r, r, paintBg);

    // Draw the image smaller than the background so a little border will be seen
    canvas.drawCircle(r, r, r - borderRadius, paint);

    squared.recycle();

    return result;
}

@Override
public String getId() {
    return getClass().getName();
}} 

5

Para Glide 4.xx

utilizar

Glide
  .with(context)
  .load(uri)
  .apply(
      RequestOptions()
        .circleCrop())
  .into(imageView)

del doc declaró que

Imágenes redondas: se sabe que CircleImageView / CircularImageView / RoundedImageView tiene problemas con TransitionDrawable (.crossFade () con .thumbnail () o .placeholder ()) y GIF animados, use un BitmapTransformation (.circleCrop () estará disponible en v4) o .dontAnimate () para solucionar el problema


4

Según esta respuesta, la forma más fácil en ambos idiomas es:

Kotlin:

Glide.with(context).load(uri).apply(RequestOptions().circleCrop()).into(imageView)

Java:

Glide.with(context).load(uri).apply(new RequestOptions().circleCrop()).into(imageView)

Esto funciona en Glide 4.XX


4

La respuesta de Roman Samoylenko fue correcta, excepto que la función ha cambiado. La respuesta correcta es

Glide.with(context)
                .load(yourImage)
                .apply(RequestOptions.circleCropTransform())
                .into(imageView);

3

Encontré una solución fácil y simple para agregar borde sobre la vista de imagen en el que el color desea establecer o agregar degradado sobre la imagen.

PASOS:

  1. Tome un diseño de marco y agregue dos imágenes. Puede establecer el tamaño según sus necesidades. Para imgPlaceHolder, necesita una imagen o color blanco que desea establecer.

        <ImageView
            android:id="@+id/imgPlaceHolder"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:src="@drawable/white_bg"/>

        <ImageView
            android:id="@+id/imgPic"
            android:layout_width="190dp"
            android:layout_height="190dp"
            android:layout_gravity="center"
            android:src="@drawable/image01"/>
    </FrameLayout>
  1. Después de colocar este código en el archivo xml, coloque debajo de la línea en el archivo java.

    Glide.with(this).load(R.drawable.image01).asBitmap().centerCrop().into(new BitmapImageViewTarget(imgPic) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable =
                    RoundedBitmapDrawableFactory.create(getResources(), resource);
            circularBitmapDrawable.setCircular(true);
            imageView.setImageDrawable(circularBitmapDrawable);
        }
    });
    
    Glide.with(this).load(R.drawable.white_bg).asBitmap().centerCrop().into(new BitmapImageViewTarget(imgPlaceHolder) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable =
                    RoundedBitmapDrawableFactory.create(getResources(), resource);
            circularBitmapDrawable.setCircular(true);
            imgTemp2.setImageDrawable(circularBitmapDrawable);
        }
    });

Esto hará que el borde de la vista de la imagen simplemente sin margen y margen adicional.

NOTA : La imagen blanca es obligatoria para el borde; de ​​lo contrario, no funcionará.

Feliz codificación :)


3

Con glide library puedes usar este código:

Glide.with(context)
    .load(imageUrl)
    .asBitmap()
    .placeholder(R.drawable.user_pic)
    .centerCrop()
    .into(new BitmapImageViewTarget(img_profPic) {
        @Override
        protected void setResource(Bitmap resource) {
            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource);

            circularBitmapDrawable.setCircular(true);
            img_profPic.setImageDrawable(circularBitmapDrawable);
        }
    });

También puede hacer una imagen redondeada mediante la biblioteca Glid.
priti

2

Lo estaba buscando antes y lo hice de la manera más fácil, espero que les guste esto.

 //crete this method into your Utils class and call this method wherever you want to use.
    //you can set these placeHolder() and error() image static as well. I made it as comment inside this method, then no need to use [placeHolderUrl and errorImageUrl] parameters. remove it from this method.
    public static void loadImage(final Activity context, ImageView imageView, String url, int placeHolderUrl, int errorImageUrl) {
        if (context == null || context.isDestroyed()) return;

        //placeHolderUrl=R.drawable.ic_user;
        //errorImageUrl=R.drawable.ic_error;
            Glide.with(context) //passing context
                    .load(getFullUrl(url)) //passing your url to load image.
                    .placeholder(placeHolderUrl) //this would be your default image (like default profile or logo etc). it would be loaded at initial time and it will replace with your loaded image once glide successfully load image using url.
                    .error(errorImageUrl)//in case of any glide exception or not able to download then this image will be appear . if you won't mention this error() then nothing to worry placeHolder image would be remain as it is.
                    .diskCacheStrategy(DiskCacheStrategy.ALL) //using to load into cache then second time it will load fast.
                    .transform(new CircleTransform(context))//this CircleTransform class help to crop an image as circle.
                    .animate(R.anim.fade_in) // when image (url) will be loaded by glide then this face in animation help to replace url image in the place of placeHolder (default) image.
                    .fitCenter()//this method help to fit image into center of your ImageView
                    .into(imageView); //pass imageView reference to appear the image.
    } 

CircleTransform.java

  public class CircleTransform extends BitmapTransformation {
    public CircleTransform(Context context) {
        super(context);

        if(context==null)
            return;
    }

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;


        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    @Override
    public String getId() {
        return getClass().getName();
    }
}

fade_in.xml para desvanecerse en la animación.

    <set xmlns:android="http://schemas.android.com/apk/res/android">
<!--THIS ANIMATION IS USING FOR FADE IN -->

<alpha
    android:duration="800"
    android:fromAlpha="0.0"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:toAlpha="1.0" />

finalmente para llamar a este método.

Utils.loadImage(YourClassName.this,mImageView,url,R.drawable.ic_user,R.drawable.ic_error);

2

Simplemente puede llamar al constructor RoundedCornersTransformation, que tiene entrada de tipo cornerType. Me gusta esto:

Glide.with(context)
            .load(bizList.get(position).getCover())
            .bitmapTransform(new RoundedCornersTransformation(context,20,0, RoundedCornersTransformation.CornerType.TOP))
            .into(holder.bizCellCoverImg);

pero primero debe agregar Transformaciones de deslizamiento a su proyecto.


2

Aquí hay una forma más modular y limpia de recortar en círculo su mapa de bits en Glide:

  1. Cree una transformación personalizada extendiendo y BitmapTransformationluego anule el transformmétodo de esta manera:

Para Glide 4.xx

public class CircularTransformation extends BitmapTransformation {

@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
    RoundedBitmapDrawable circularBitmapDrawable =
            RoundedBitmapDrawableFactory.create(null, toTransform);
    circularBitmapDrawable.setCircular(true);
    Bitmap bitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    circularBitmapDrawable.setBounds(0, 0, outWidth, outHeight);
    circularBitmapDrawable.draw(canvas);
    return bitmap;
    }

@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {}

}

Para Glide 3.xx

public class CircularTransformation extends BitmapTransformation {

@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
    RoundedBitmapDrawable circularBitmapDrawable =
            RoundedBitmapDrawableFactory.create(null, toTransform);
    circularBitmapDrawable.setCircular(true);
    Bitmap bitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    circularBitmapDrawable.setBounds(0, 0, outWidth, outHeight);
    circularBitmapDrawable.draw(canvas);
    return bitmap;
    }

@Override
public String getId() {
    // Return some id that uniquely identifies your transformation.
    return "CircularTransformation";
    }

}
  1. Luego configúrelo en Glide Builder donde lo necesite:
Glide.with(yourActivity)
   .load(yourUrl)
   .asBitmap()
   .transform(new CircularTransformation())
   .into(yourView);

Espero que esto ayude :)


2
private void setContactImage(@NonNull ViewHolder holder, ClsContactDetails clsContactDetails) {
    Glide.with(context).load(clsContactDetails.getPic())
        .apply(new RequestOptions().centerCrop().circleCrop().placeholder(R.mipmap.ic_launcher)).into(holder.ivPersonImage);
}

2
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'


RequestOptions options=new RequestOptions();
        options.centerCrop().placeholder(getResources().getDrawable(R.drawable.user_placeholder));
        Glide.with(this)
                .load(preferenceSingleTon.getImage())
                .apply(options)
                .into(ProfileImage);

2

Recorte circular + marcador de posición + fundido cruzado

 Glide.with(context!!)
                    .load(randomImage)
                    .apply(RequestOptions.bitmapTransform(CircleCrop()).error(R.drawable.nyancat_animated))
                    .transition(DrawableTransitionOptions()
                            .crossFade())
                    .into(picture)

ingrese la descripción de la imagen aquí


1

Glide versión 4.6.1

Glide.with(context)
.load(url)
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
.into(imageView);

1

En este caso, necesito agregar sombras, y la elevación de imageView no funciona

implementación "com.github.bumptech.glide: glide: 4.10.0"

XML

<FrameLayout
    android:id="@+id/fl_image"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_margin="10dp"
    android:background="@drawable/card_circle_background"
    android:elevation="8dp">

    <ImageView
        android:id="@+id/iv_item_employee"
        android:layout_width="60dp"
        android:layout_height="60dp"
        tools:background="@color/colorPrimary" />
</FrameLayout>

Forma dibujable

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">
     <solid android:color="@color/white"/>
</shape>

Configuración de deslizamiento

Glide.with(this)
    .asBitmap()
    .load(item.image)
    .apply(RequestOptions.circleCropTransform())
    .into(iv_item_employee)

0

Tienes que usar CircularImageView para mostrar ese tipo de imagen ...

Estás utilizando la biblioteca Glide que solía cargar imágenes.

Cree un archivo de clase en su proyecto y cárguelo en la vista de imagen ... y obtendrá el resultado deseado ...

Intenta seguir el código ...

XML

 <com.yourpackage.CircularImageView
    android:id="@+id/imageview"
    android:layout_width="96dp"
    android:layout_height="96dp"
    app:border="true"
    app:border_width="3dp"
    app:border_color="@color/white"
    android:src="@drawable/image" />

CircularImageView.java

public class CircularImageView extends ImageView {
    private int borderWidth;
    private int canvasSize;
    private Bitmap image;
    private Paint paint;
    private Paint paintBorder;

    public CircularImageView(final Context context) {
        this(context, null);
    }

    public CircularImageView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.circularImageViewStyle);
    }

    public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // init paint
        paint = new Paint();
        paint.setAntiAlias(true);

        paintBorder = new Paint();
        paintBorder.setAntiAlias(true);

        // load the styled attributes and set their properties
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);

        if(attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
            int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
            setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
            setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
        }

        if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
            addShadow();
    }

    public void setBorderWidth(int borderWidth) {
        this.borderWidth = borderWidth;
        this.requestLayout();
        this.invalidate();
    }

    public void setBorderColor(int borderColor) {
        if (paintBorder != null)
            paintBorder.setColor(borderColor);
        this.invalidate();
    }

    public void addShadow() {
        setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
        paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
    }

    @Override
    public void onDraw(Canvas canvas) {
        // load the bitmap
        image = drawableToBitmap(getDrawable());

        // init shader
        if (image != null) {

            canvasSize = canvas.getWidth();
            if(canvas.getHeight()<canvasSize)
                canvasSize = canvas.getHeight();

            BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint.setShader(shader);

            // circleCenter is the x or y of the view's center
            // radius is the radius in pixels of the cirle to be drawn
            // paint contains the shader that will texture the shape
            int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // The parent has determined an exact size for the child.
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // The parent has not imposed any constraint on the child.
            result = canvasSize;
        }

        return result;
    }

    private int measureHeight(int measureSpecHeight) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpecHeight);
        int specSize = MeasureSpec.getSize(measureSpecHeight);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // Measure the text (beware: ascent is a negative number)
            result = canvasSize;
        }

        return (result + 2);
    }

    public Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable == null) {
            return null;
        } else if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }
}

Nota :

Puedes usar

CircularImageView imgIcon = (CircularImageView)findViewById(R.id.imageview);

o

ImageView imgIcon = (ImageView)findViewById(R.id.imageview);

no afectará a sus otras bibliotecas ... no tiene que cambiar su código para descargar imágenes ni nada más ... simplemente se puede definir usando XML también ...


3
He intentado Glide + CircularImageView (y RoundedImageView) y no funciona bien si comienzas a usar marcador de posición (mientras tu imagen se descarga) y animaciones de apariencia. Picasso no tiene este problema. Puede obtener más información al respecto aquí: github.com/vinc3m1/RoundedImageView/issues/76
zmicer

Simplemente use .asBitmap en la llamada Glide y funcionará bien.
granko87

Requiere llamar a .dontAnimate () en glide, lo cual no es aceptable
Greg Ennis
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.