236

So, anybody know how to display an image with rounded corners with Glide? I am loading an image with Glide, but I don't know how to pass rounded params to this library.

I need display image like following example:

enter image description here

Charuක
  • 12,953
  • 5
  • 50
  • 88
SBotirov
  • 13,872
  • 7
  • 59
  • 81
  • 2
    i have use https://github.com/hdodenhof/CircleImageView for ronded image view – MilapTank Aug 13 '14 at 05:51
  • 2
    I know how to use Glide lib with CircleImageView, but I search possible way do this with only Glide lib. Have a any method in Glide lib to do this or it is not supported? – SBotirov Aug 13 '14 at 07:44

28 Answers28

590

Glide V4:

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

Glide V3:

You can use RoundedBitmapDrawable for circular images with Glide. No custom ImageView is required.

 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);
        }
    });
Fattie
  • 27,874
  • 70
  • 431
  • 719
jimmy0251
  • 16,293
  • 10
  • 36
  • 39
69

Check this post, glide vs picasso...
Edit: the linked post doesn't call out an important difference in the libraries. Glide does the recycling automatically. See TWiStErRob's comment for more.

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();
    }
} 
TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
Harsha Vardhan
  • 3,324
  • 2
  • 17
  • 22
  • sounds interesting. Does it work well with API 21's Outline ? – Teovald Nov 06 '14 at 16:55
  • hmm, I might use this then. I will try to simply use a custom view though, I would like not to have to create a second bitmap :) . Also, you should always use the bitmap pool in order to try to get a bitmap from there :) – Teovald Nov 07 '14 at 09:05
  • Beware of using `public String getId()` the way it shown in code since it returns the same id for all images and thus it could happen that glide will set old rounded images while without transformations it gonna set the correct image! I don't know how glide works but seems like it caches images transformations (to avoid hard calcs I assume). And the id is used as the id of transformed image. I added an url of image to constructor and made mentioned method returning resulting id like: `this.id = String.format("%s:%s",this.getClass().getSimpleName(),id);` – Stan Feb 25 '15 at 19:54
  • 2
    Stan only requirement for Transformation ids is that they are unique among all Transformations, so the usage here is correct. Cache keys will include both the source id and the transformation id, so the transformation id is a mixin rather than a replacement. See https://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation#cache-keys – Sam Judd Mar 01 '15 at 18:49
  • I fixed a resource reuse problem discovered in [Glide#408](https://github.com/bumptech/glide/issues/408) and also note that Glide 4.0 will have a Circle transformation built in. – TWiStErRob Apr 17 '15 at 18:16
  • 4
    Is there a way to apply transformation to placeholder? – Sinigami Nov 10 '15 at 17:18
  • @Sinigami AFAIK, no there is not. Placeholders are applied synchronously whereas transformations are async by nature. – Teovald Jan 22 '16 at 12:32
  • As mentioned in [TWiStErRob's comment](http://vardhan-justlikethat.blogspot.jp/2014/09/android-image-loading-libraries-picasso.html), the toTransform Bitmap should never be recycled. But since Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); might create a copy, wouldn't it be good to check if source equals squared and if not recycle it in the end? – AljoSt Jun 17 '16 at 04:37
68

The easiest way (requires Glide 4.x.x)

Glide.with(context).load(uri).apply(RequestOptions.circleCropTransform()).into(imageView)
NoHarmDan
  • 492
  • 5
  • 16
Roman Samoilenko
  • 932
  • 12
  • 25
33

Try this way

code

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>
PathoS
  • 439
  • 4
  • 9
  • This answer should be accepted. It gives everything you need, it's great! I would also add that you can add padding to xml so your image is not touching the border ;) – Kratos Feb 09 '23 at 21:55
10

its very simple i have seen Glide library its very good library and essay base on volley Google's library

usethis library for rounded image view

https://github.com/hdodenhof/CircleImageView

now

//For a simple view:

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

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

//For a list:

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

and in 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" />
MilapTank
  • 9,988
  • 7
  • 38
  • 53
  • 2
    Like mentioned in previous answer comment this way doesn't work well either. At least for 'de.hdodenhof:circleimageview:1.2.2' + 'com.github.bumptech.glide:glide:3.5.2'. Checked and double checked. Also the same issue with glide 3.4.+ and circleimageview 1.2.1 – Stan Feb 25 '15 at 19:45
  • +1 for the .centerCrop(). Worked for me with the [DiamondImageView](https://github.com/siyamed/android-shape-imageview) **plus** .asBitmap(). – felippe Sep 25 '15 at 18:11
  • 1
    Requires calling .dontAnimate() on glide which is not acceptable – Greg Ennis Apr 22 '16 at 01:14
  • +1 But also note that [Loading Internet Images with Glide](https://github.com/hdodenhof/CircleImageView/issues/57) – hedgehog Aug 25 '16 at 11:50
9

The other solutions did not work for me. I found they all have significant drawbacks:

  • Solutions using glide transformations do not work with placeholders
  • Solutions using rounded image views do not work with animations (i.e. crossfade)
  • Solutions using a generic method of a parent that clips its children (i.e. the accepted answer here) do not work well with glide

It is really interesting that after fumbling around with this I found the Fresco library page about rounded corners and circles in which they list basically the same limitations and conclude with the statement:

there is no really good solution for rounding corners on Android and one has to choose between the aforementioned trade-offs

Unbelievable that at this time we still dont have a real solution. I have an alternate solution based on the link I put above. The drawback with this approach is that it assumes your background is a solid color (the corners aren't really transparent). You would use it like this:

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

The gist is here and full code here:

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;
    }
}
Community
  • 1
  • 1
Greg Ennis
  • 14,917
  • 2
  • 69
  • 74
7

Now in Glide V4 you can directly use CircleCrop()

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

Built in types

  • CenterCrop
  • FitCenter
  • CircleCrop
Gibolt
  • 42,564
  • 15
  • 187
  • 127
Prashant Gosai
  • 1,186
  • 1
  • 10
  • 18
7

According to this answer, the easiest way in both languages is:

Kotlin:

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

Java:

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

This works on Glide 4.X.X

Amir Hossein Ghasemi
  • 20,623
  • 10
  • 57
  • 53
5

Use this transformation, it will work fine.

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();
}} 
ROHIT PARMAR
  • 901
  • 15
  • 26
5

For Glide 4.x.x

use

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

from doc it stated that

Round Pictures: CircleImageView/CircularImageView/RoundedImageView are known to have issues with TransitionDrawable (.crossFade() with .thumbnail() or .placeholder()) and animated GIFs, use a BitmapTransformation (.circleCrop() will be available in v4) or .dontAnimate() to fix the issue

Basi
  • 3,009
  • 23
  • 28
5

Roman Samoylenko's answer was correct except the function has changed. The correct answer is

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

I found one easy and simple solution for add border over imageview in which color want to set or add gradient over image.

STEPS:

  1. Take one frame layout and add two images.You can set size as per your requirement. For imgPlaceHolder , you need one white image or color which you want to set.

        <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. After placing this code on xml file , put below line in java file.

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

This will make border of imageview simply with out any extra padding and margin.

NOTE : White image is compulsory for border otherwise it will not work.

Happy codding :)

Anand Savjani
  • 2,484
  • 3
  • 26
  • 39
3

With glide library you can use this code:

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);
        }
    });
Adam
  • 5,403
  • 6
  • 31
  • 38
priti
  • 892
  • 9
  • 9
3

Circle crop + placeholder + crossfade

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

enter image description here

Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
3

You can also use this implementation, although it is noteworthy that this implementation is based on the dagger Hilt

Provider implementation

@Module
@Named("circleCrop")
@InstallIn(SingletonComponent::class)
object AppModule {
    @Singleton
    @Provides
    fun provideGlideInstance(
        @ApplicationContext context: Context
    ) = Glide.with(context).setDefaultRequestOptions(
        RequestOptions()
            .placeholder(R.drawable.logo)
            .error(R.drawable.logo)
            .apply(RequestOptions().circleCropTransform())
            .diskCacheStrategy(DiskCacheStrategy.DATA)
    )
}

Dependency injection

@Inject
@Named("circleCrop")
 lateinit var glide: RequestManager

Load image

    glide.load(hotel.image).into(imgItemSearch)
Asghar Hosseini
  • 239
  • 1
  • 5
  • 14
2

I was looking for it earlier and I made it in very easiest way, I hope you would like this.

 //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 for fade in animation .

    <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" />

finally to call this method.

Utils.loadImage(YourClassName.this,mImageView,url,R.drawable.ic_user,R.drawable.ic_error);
Abdul Rizwan
  • 3,904
  • 32
  • 31
2

You can simply call the RoundedCornersTransformation constructor, which has cornerType enum input. Like this:

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

but first you have to add Glide Transformations to your project.

BabakHSL
  • 622
  • 1
  • 8
  • 18
2

Here is a more modular and cleaner way to circle crop your bitmap in Glide:

  1. Create a custom transformation by extending BitmapTransformation then override transform method like this :

For Glide 4.x.x

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

}

For Glide 3.x.x

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. Then set it in Glide builder where you need it:
Glide.with(yourActivity)
   .load(yourUrl)
   .asBitmap()
   .transform(new CircularTransformation())
   .into(yourView);

Hope this helps :)

Behzad Bahmanyar
  • 6,195
  • 4
  • 35
  • 41
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);
}
Deepak Rajput
  • 731
  • 6
  • 20
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);
Nick
  • 138,499
  • 22
  • 57
  • 95
Android Helper
  • 161
  • 1
  • 3
1

Glide version 4.6.1

Glide.with(context)
.load(url)
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
.into(imageView);
nesimtunc
  • 849
  • 7
  • 28
1

In this case I need add shadows, and imageView elevation not working

implementation "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>

Shape drawable

<?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>

Glide Configuration

Glide.with(this)
    .asBitmap()
    .load(item.image)
    .apply(RequestOptions.circleCropTransform())
    .into(iv_item_employee)
Diego Sanchez
  • 1,369
  • 1
  • 11
  • 5
1

In my case; .apply(RequestOptions.circleCropTransform()) (4.11) not worked. Because I was trying it with the ImageButton. When I change with (clickable) ImageView, it worked and looked the way I wanted it to.

Mete
  • 2,805
  • 1
  • 28
  • 38
1

For Jetpack Compose you can use Modifier.clip(CircleShape)

Here is an example:

GlideImage(
     model = imageUrl,
     contentDescription = "",
     contentScale = ContentScale.Crop,
     modifier = Modifier
     .size(20.dp)
     .clip(CircleShape)
)
Jonny Right
  • 528
  • 4
  • 10
0

You have to use CircularImageView to Display that type of Image...

You are using Glide library which used to load images..

Create One ClassFile in your Project and Load it in Imageview... and You will get Desired Result...

Try Following Code...

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

Note :

You can use

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

or

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

it wont affect your other libraries... dont have to change your code for downloading image or anything else... it simply can be defined using XML too..

Pragnesh Ghoda シ
  • 8,318
  • 3
  • 25
  • 40
  • 3
    I have tried Glide + CircularImageView (and RoundedImageView) and it doesn't work well if you start using placeholder (while you image is getting downloaded) and appearance animations. Picasso doesn't have this issue. You can red more about it here: https://github.com/vinc3m1/RoundedImageView/issues/76 – zmicer Feb 18 '15 at 12:30
  • Just use .asBitmap in Glide call and it will work fine. – granko87 Nov 18 '15 at 10:27
  • Requires calling .dontAnimate() on glide which is not acceptable – Greg Ennis Apr 22 '16 at 01:13
0
                Glide.with(MainActivity.this)
                        .load(personPhoto)
                        .transition(withCrossFade(500))
                        .apply(RequestOptions.circleCropTransform())
                        .thumbnail(0.5f)
                        .into(imageView);

            
0

Don't attach too much functions such as placeholder(), transition(), etc, just make it as simple as this piece of code, it will then work.

                        Glide.with(mContext)
                            .load(datas.getUser_img())
                            .centerCrop()
                            .into(ivAvator);
0

Easy solution by using this library implementation 'de.hdodenhof:circleimageview:3.1.0'

<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/profile_image"
android:layout_width="96dp"
android:layout_height="96dp"
android:src="@drawable/profile"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>

Glide.load(url)
.centerCrop()
.placeholder(R.drawable.loading_spinner)
.animate(R.anim.fade_in)
.into(YourImageView);
Ali Hassan
  • 188
  • 4
  • 8