How to make an ImageView with rounded corners?

AndroidImageviewAndroid ImageviewAndroid ImageRounded Corners

Android Problem Overview


In Android, an ImageView is a rectangle by default. How can I make it a rounded rectangle (clip off all 4 corners of my Bitmap to be rounded rectangles) in the ImageView?

Android Solutions


Solution 1 - Android

This is pretty late in response, but for anyone else that is looking for this, you can do the following code to manually round the corners of your images.

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

This isn't my code, but I've used it and it's works wonderfully. I used it as a helper within an ImageHelper class and extended it just a bit to pass in the amount of feathering I need for a given image.

Final code looks like this:

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

Solution 2 - Android

Another easy way is to use a CardView with the corner radius and an ImageView inside:

  <androidx.cardview.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"
                />
        </androidx.cardview.widget.CardView>

enter image description here

Solution 3 - Android

Clipping to rounded shapes was added to the View class in API 21.

Just do this:

  • Create a rounded shape drawable, something like this:

res/drawable/round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>
  • Set the drawable as your ImageView's background: android:background="@drawable/round_outline"
  • According to this documentation, then all you need to do is add android:clipToOutline="true"

Unfortunately, there's a bug and that XML attribute is not recognized. Luckily, we can still set up clipping in Java:

  • In your activity or fragment: ImageView.setClipToOutline(true)

Here's what it will look like:

enter image description here

Note:

This method works for any drawable shape (not just rounded). It will clip the ImageView to whatever shape outline you've defined in your Drawable xml.

Special note about ImageViews

setClipToOutline() only works when the View's background is set to a shape drawable. If this background shape exists, View treats the shape's outline as the borders for clipping and shadowing purposes.

This means, if you want to use setClipToOutline() to round the corners on an ImageView, your image must be set using android:src instead of android:background (since background must be set to your rounded shape). If you MUST use background to set your image instead of src, you can use this workaround:

  • Create a layout and set its background to your shape drawable
  • Wrap that layout around your ImageView (with no padding)
  • The ImageView (including anything else in the layout) will now display with rounded layout shape.

Solution 4 - Android

While the above answer works, Romain Guy (a core Android developer) shows a better method in his blog which uses less memory by using a shader not creating a copy of the bitmap. The general gist of the functionality is here:

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

The advantages of this over other methods is that it:

  • does not create a separate copy of the bitmap, which uses a lot of memory with large images [vs most of the other answers here]
  • supports antialisasing [vs clipPath method]
  • supports alpha [vs xfermode+porterduff method]
  • supports hardware acceleration [vs clipPath method]
  • only draws once to the canvas [vs xfermode and clippath methods]

I've created a RoundedImageView based off this code that wraps this logic into an ImageView and adds proper ScaleType support and an optional rounded border.

Solution 5 - Android

Starting with the version 1.2.0-alpha03 of the Material Components Library there is the new ShapeableImageView.

You can use something like:

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

with in your themes.xml:

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

Or programmatically:

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

enter image description here


With jetpack compose you can apply a clip Modifier using a RoundedCornerShape:

Image(
    painter = painterResource(R.drawable.xxxx),
    contentDescription = "xxxx",
    contentScale = ContentScale.Crop,            
    modifier = Modifier
        .size(64.dp)
        .clip(RoundedCornerShape(8.dp))             
)

Solution 6 - Android

In the v21 of the Support library there is now a solution to this: it's called RoundedBitmapDrawable.

It's basically just like a normal Drawable except you give it a corner radius for the clipping with:

setCornerRadius(float cornerRadius)

So, starting with Bitmap src and a target ImageView, it would look something like this:

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

Solution 7 - Android

A quick xml solution -

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

You can set your desired width, height and radius on CardView and scaleType on ImageView.

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

Solution 8 - Android

I have done by 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);
    }
}

How to use:

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

Output:

enter image description here

Hope this would help you.

Solution 9 - Android

I found that both methods were very helpful in coming up with a working solution. Here is my composite version, that is pixel independent and allows you to have some square corners with the rest of the corners having the same radius (which is the usual use case). With thanks to both of the solutions above:

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

Also, I overrode ImageView to put this in so I could define it in xml. You may want to add in some of the logic that the super call makes here, but I've commented it as it's not helpful in my case.

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

Hope this helps!

Solution 10 - Android

Rounded image Using ImageLoader here

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

Or you can user Picasso Library from 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);

you can download RoundedTransformation file here here

Solution 11 - Android

As all the answers seemed too complicated for me just for round corners I thought and came to another solution which I think is worth to share, just with XML in case you have some space around the image:

Create a bordered shape with transparent content like this:

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

Then in a RelativeLayout you can first place your image and then in the same location above the shape with another ImageView. The cover-shape should be larger in size by the amount of the border width. Be careful to take a larger corner radius as the outer radius is defined but the inner radius is what covers your image.

Hope it helps somebody, too.

Edit as per CQM request the relative layout example:

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

Solution 12 - Android

My implementation of ImageView with rounded corners widget, that (down||up)sizes image to required dimensions. It utilizes code form 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);

	}

}

Solution 13 - Android

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

First, setup Glide version 4+:

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

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

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

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

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {}

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

After adding these files, build your project.

Then use it in your code like this:

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

Solution 14 - Android

There is a cool library that allows you to shape imageviews.

Here is an example:

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

Shape definition:

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

Result:

result

Solution 15 - Android

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

public class RoundedImageView extends ImageView {

    public RoundedImageView(Context context) {
        super(context);
    }

    public RoundedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        float radius = 0.1f;
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
        rid.setCornerRadius(bitmap.getWidth() * radius);
        super.setImageDrawable(rid);
    }
}

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

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

Usage:

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

Preview with imageView and custom imageView:

enter image description here

Solution 16 - Android

Kotlin

import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
rounded.cornerRadius = 20f
profileImageView.setImageDrawable(rounded)

To make ImageView Circular we can change cornerRadius with:

rounded.isCircular = true

Solution 17 - Android

Apply a shape to your imageView as below:

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

it may be helpful to you friend.

Solution 18 - Android

You should extend ImageView and draw your own rounded rectangle.

If you want a frame around the image you could also superimpose the rounded frame on top of the image view in the layout.

[edit]Superimpose the frame on to op the original image, by using a FrameLayout for example. The first element of the FrameLayout will be the image you want to diplay rounded. Then add another ImageView with the frame. The second ImageView will be displayed on top of the original ImageView and thus Android will draw it's contents above the orignal ImageView.

Solution 19 - Android

Props to George Walters II above, I just took his answer and extended it a bit to support rounding individual corners differently. This could be optimized a bit further (some of the target rects overlap), but not a whole lot.

I know this thread is a bit old, but its one of the top results for queries on Google for how to round corners of ImageViews on 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;
}

Solution 20 - Android

Romain Guy is where it's at.

Minified version as follows.

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

Solution 21 - Android

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

EDIT

Here's the answer in a nutshell:

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

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

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

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

Solution 22 - Android

None of the methods provided in the answers worked for me. I found the following way works if your android version is 5.0 or above:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    ViewOutlineProvider provider = new ViewOutlineProvider() {
        @Override
        public void getOutline(View view, Outline outline) {
            int curveRadius = 24;
            outline.setRoundRect(0, 0, view.getWidth(), (view.getHeight()+curveRadius), curveRadius);
        }
    };
    imageview.setOutlineProvider(provider);
    imageview.setClipToOutline(true);
}

No xml shapes to be defined, and the code above create corners only for top, which normal methods won't work. If you need 4 corners to be rounded, remove:

"+ curveRadius"  

From the parameter for bottom in setRoundRect. You can further expand the shape to any others by specifying outlines that suit your needs. Check out the following link:

Android Developer Documentation.


Note, as with any measure in Android, you have to "convert" the size typically from DP. In the example above, say you want the radius to be 24

                            int curveRadius = 24;

For example you may be later adding a border in a drawable with the radius set as "24" and you wish it to match. Hence,

    float desiredRadius = 24;
    float radiusConverted = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            desiredRadius,
            itemView.getContext().getResources().getDisplayMetrics());

and then

                            int curveRadius = radiusConverted;

Solution 23 - Android

It can be done with ShapeableImageView and ShapeAppearanceOverlay:

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/avatar"
    android:layout_width="64dp"
    android:layout_height="64dp"
    android:padding="4dp"
    app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"/>

Where style ShapeAppearanceOverlay.Avatar resides in res/values/styles.xml:

<style name="ShapeAppearanceOverlay.Avatar" parent="ShapeAppearance.MaterialComponents.SmallComponent">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">50%</item>
</style>

This just need equal layout_height and layout_width set, else with will be a pill an no circle.

Solution 24 - Android

Why not do clipping in draw()?

Here is my solution:

  • Extend RelativeLayout with clipping
  • Put ImageView (or other views) into the layout:

Code:

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

}

Solution 25 - Android

The following creates a rounded rectangle layout object that draws a rounded rectangle around any child objects that are placed in it. It also demonstrates how to create views and layouts programmatically without using the layout xml files.

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

The class for RoundedRectangle layout object is as defined here:

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

}

Solution 26 - Android

If you are using Glide Library this would be helpful:

Glide.with(getApplicationContext())
     .load(image_url)
     .asBitmap()
     .centerCrop()
     .into(new BitmapImageViewTarget(imageView) {
        @Override
        protected void setResource(Bitmap resource) {
          RoundedBitmapDrawable circularBitmapDrawable =
                       RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource);
          circularBitmapDrawable.setCornerRadius(dpToPx(10));
          circularBitmapDrawable.setAntiAlias(true);
          imageView.setImageDrawable(circularBitmapDrawable);
        }
     });


public int dpToPx(int dp) {
  DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
  return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}

Solution 27 - Android

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

public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) {
	
	Bitmap inpBitmap = bitmap;
	int width = 0;
	int height = 0;
	width = inpBitmap.getWidth();
	height = inpBitmap.getHeight();
	
	if (width <= height) {
		height = width;
	} else {
		width = height;
	}
	
    Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, width, height);
    final RectF rectF = new RectF(rect);
    final float roundPx = pixels;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(inpBitmap, rect, rect, paint);

    return output;
}

Solution 28 - Android

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

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

Solution 29 - Android

you can use only ImageView in your layout and using glide, you can apply round corners using this method.

first in your gradle write,

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

for image with rounded corners,

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

call method :

loadImageWithCorners("your url","your imageview");

Solution 30 - Android

By using below code you can change top corner radius

val image = findViewById<ImageView>(R.id.image)
val curveRadius = 20F

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    image.outlineProvider = object : ViewOutlineProvider() {

        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        override fun getOutline(view: View?, outline: Outline?) {
            outline?.setRoundRect(0, 0, view!!.width, (view.height+curveRadius).toInt(), curveRadius)
        }
    }

    image.clipToOutline = true

}

Solution 31 - Android

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

public static Bitmap getRoundBitmap(Bitmap bitmap) {

    int min = Math.min(bitmap.getWidth(), bitmap.getHeight());

    Bitmap bitmapRounded = Bitmap.createBitmap(min, min, bitmap.getConfig());
    
    Canvas canvas = new Canvas(bitmapRounded);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min/2, min/2, paint);

    return bitmapRounded;
}

Solution 32 - Android

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

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

Solution 33 - Android

For the ones that are using Glide and Kotlin, you can achieve so by extending RequestBuilder

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

and use as;

 GlideApp.with(context)
            .load(url)
            .roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
            .into(imgView)

Solution 34 - Android

for rounded border use below code

  <com.google.android.material.card.MaterialCardView
                        android:id="@+id/circle"
                        android:layout_width="45dp"
                        android:layout_height="45dp"
                        android:layout_marginStart="5dp"

                        app:cardCornerRadius="25dp"
                        app:strokeColor="@color/colorDarkGreen"

                        app:strokeWidth="1dp">

                        <ImageView
                            android:id="@+id/toolbarProfile"
                            android:scaleType="fitXY"

                            android:layout_width="match_parent"
                            android:layout_height="match_parent"

                            android:src="@drawable/avater" />
                    </com.google.android.material.card.MaterialCardView>

Solution 35 - Android

Try the Material Components Library and use the ShapeableImageView. Somethig like this :

    imageView=new ShapeableImageView(context);
    imageView.setShapeAppearanceModel(
            imageView.getShapeAppearanceModel().toBuilder()
                    .setAllCornerSizes(20).build());

enter image description here

Solution 36 - Android

Quite a lot of answers!

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

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

  1. Set the FrameLayout to the width and height - in my case the size of the image (50dp).

  2. Place the ImageView that has the src = "@drawable/...", above the ImageView that has the image. Give it an id, in my case I called it iconShape

  3. Drawable mask.xml should have a solid colour of #ffffffff

  4. If you want to dynamically change the circle colour in your code, do

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

Solution 37 - Android

You can try this library - RoundedImageView

It is:

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

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

Solution 38 - Android

Use this to get circular image with border-

    public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) {
	if (bitmap == null || bitmap.isRecycled()) {
		return null;
	}
	int borderWidth=(int)(bitmap.getWidth()/40);
	final int width = bitmap.getWidth() + borderWidth;
	final int height = bitmap.getHeight() + borderWidth;

	Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
			Bitmap.Config.ARGB_8888);
	BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP,
			TileMode.CLAMP);
	Paint paint = new Paint();
	paint.setAntiAlias(true);
	paint.setShader(shader);

	Canvas canvas = new Canvas(canvasBitmap);
	float radius = width > height ? ((float) height) / 2f
			: ((float) width) / 2f;
	canvas.drawCircle(width / 2, height / 2, radius, paint);
	paint.setShader(null);
	paint.setStyle(Paint.Style.STROKE);
	paint.setColor(bordercolor);
	paint.setStrokeWidth(borderWidth);
	canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2,
			paint);
	return canvasBitmap;
}

Solution 39 - Android

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

Advantages:

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

Code:

public class RoundedCornersView extends View {
    private float mRadius;
    private int mColor = Color.WHITE;
    private Paint mPaint;
    private Path mPath;

    public RoundedCornersView(Context context) {
        super(context);
        init();
    }

    public RoundedCornersView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.RoundedCornersView,
                0, 0);

        try {
            setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
            setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
        } finally {
            a.recycle();
        }
    }

    private void init() {
        setColor(mColor);
        setRadius(mRadius);
    }

    private void setColor(int color) {
        mColor = color;
        mPaint = new Paint();
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        invalidate();
    }

    private void setRadius(float radius) {
        mRadius = radius;
        RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
        mPath = new Path();
        mPath.moveTo(0,0);
        mPath.lineTo(0, mRadius);
        mPath.arcTo(r, 180, 90);
        mPath.lineTo(0,0);
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        /*This just draws 4 little inverted corners */

        int w = getWidth();
        int h = getHeight();
        canvas.drawPath(mPath, mPaint);
        canvas.save();
        canvas.translate(w, 0);
        canvas.rotate(90);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.save();
        canvas.translate(w, h);
        canvas.rotate(180);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.translate(0, h);
        canvas.rotate(270);
        canvas.drawPath(mPath, mPaint);
    }
}

Solution 40 - Android

Thanks to melanke you can use a custom classand create a custom circular ImageView.

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;

public class MLRoundedImageView extends android.support.v7.widget.AppCompatImageView {

    public MLRoundedImageView(Context context) {
        super(context);
    }

    public MLRoundedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    protected void onDraw(Canvas canvas) {

        Drawable drawable = getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

        int w = getWidth(), h = getHeight();

        Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

    public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
        Bitmap sbmp;

        if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
            float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
            float factor = smallest / radius;
            sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
        } else {
            sbmp = bmp;
        }

        Bitmap output = Bitmap.createBitmap(radius, radius,
                Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xffa19774;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);

        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f,
                radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(sbmp, rect, rect, paint);

        return output;
    }

}

And then use it in XML like:

<your.package.name.MLRoundedImageView
..
/>

Source

Solution 41 - Android

For Glide 4.x.x

use this simple code

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

Solution 42 - Android

you can use roundedImageView Library very easy:

compile 'com.makeramen:roundedimageview:2.3.0'

and then:

<com.makeramen.roundedimageview.RoundedImageView
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@+id/img_episode"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:elevation="7dp"
  app:riv_border_color="@color/colorPrimary"
  app:riv_border_width="1dip"
  app:riv_corner_radius="10dip"
  app:riv_mutate_background="true"
  />

Solution 43 - Android

Easiest solution I think is something like this :-

Step 1 - Create a shape drawable file as below :-

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="@color/white" />

    <corners android:radius="@dimen/dimen_10dp" />

    <stroke
        android:width="1dp"
        android:color="@color/white" />
</shape>

Step 2 - Use above drawable in code.

Drawable drawable = ContextCompat.getDrawable(mActivity, R.drawable.photos_round_shape);
            drawable.mutate().setColorFilter(randomColor, PorterDuff.Mode.SRC_ATOP);
            imageView.setBackground(drawable);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
               imageView.setClipToOutline(true);
            }

Glide.with(mContext)
                .setDefaultRequestOptions(getNoAnimationOptions())
                .load(url)
                .into(imageView);

Hope this helps.

Solution 44 - Android

***The question is old, I know, but here's another simpler way of rounding an image:

This is a programmatic method.

Create your void and ...

} public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.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(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint); return output;

Load your image, then set the rounded corners

imageview1.setImageResource(R.drawable.yourimage);

Bitmap bm = ((android.graphics.drawable.BitmapDrawable) imageview1.getDrawable()).getBitmap();
imageview1.setImageBitmap(getRoundedCornerBitmap(bm, 30)); 

With 30 being your radius and you'll get something like this:

example of a rounded image/icon

Nevermind the way my image looks, it's a zoomed small icon

Solution 45 - Android

This isn't exactly the answer, but it's a solution that is similar. It may help people who were in the same boat as I was.

My image, an application logo, had a transparent background, and I was applying an XML gradient as the image background. I added the necessary padding/margins to the imageView in XML, then added this as my background:

<?xml version="1.0" encoding="utf-8"?>
<!-- This file defines the gradient used on the background of the main activity. -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item>
		<shape>
			<gradient
				android:type="linear"
				android:startColor="@color/app_color_light_background"
				android:endColor="@color/app_color_disabled"
				android:angle="90" />

			<!-- Round the top corners. -->
			<corners
				android:topLeftRadius="@dimen/radius_small"
				android:topRightRadius="@dimen/radius_small" />
		</shape>
	</item>
</selector>

Solution 46 - Android

In Layout Make your ImageView like:

<com.example..CircularImageView
    android:id="@+id/profile_image_round_corner"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:scaleType="fitCenter"
    android:padding="2dp"
    android:background="@null"
    android:adjustViewBounds="true"
    android:layout_centerInParent="true"
    android:src="@drawable/dummy"
    />

And Create a Class:

package com.example;

import java.util.Formatter.BigDecimalLayoutForm;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class CircularImageView extends ImageView {
 
    public CircularImageView(Context context) {
        super(context);
    }
 
    public CircularImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
 
    public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
 
        Drawable drawable = getDrawable();
 
        if (drawable == null) {
            return;
        }
 
        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
 
        int w = getWidth(), h = getHeight();
 
        Bitmap roundBitmap = getRoundBitmap(bitmap, w);
        canvas.drawBitmap(roundBitmap, 0, 0, null);
 
    }
 
    public static Bitmap getRoundBitmap(Bitmap bmp, int radius) {
        Bitmap sBmp;
        
        if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
            float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
            float factor = smallest / radius;
            sBmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
        } else {
            sBmp = bmp;
        }
      
        Bitmap output = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xffa19774;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f,
                radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(sBmp, rect, rect, paint);
 
        return output;
    }
 
}

Solution 47 - Android

If any of you are facing this problem

enter image description here

Most probably , you are using Android Studio. Due to image re-size and all in Android Studio ,you may encounter this problem. An easy fix to this problem is to decrease the radius of circle in drawCircle(). In my case i use this fix

Using canvas.drawCircle(100, 100, 90, paint); instead of canvas.drawCircle(100, 100, 100, paint); this will definitely solve your problem.

Here is finally edited code:-

  public class Profile extends ActionBarActivity {


    TextView username;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.profile);


        username= (TextView) findViewById(R.id.txt);

        String recievedusername=getIntent().getExtras().getString("toname");
        username.setText(recievedusername);


        Bitmap bm = BitmapFactory.decodeResource(getResources(),
                R.mipmap.gomez);

        Bitmap resizedBitmap = Bitmap.createScaledBitmap(bm, 200,200, false);
        Bitmap conv_bm=getCircleBitmap(resizedBitmap,100);
        // set circle bitmap
        ImageView mImage = (ImageView) findViewById(R.id.profile_image);
        mImage.setImageBitmap(conv_bm);
        // TODO Auto-generated method stub
    }
    private Bitmap getCircleBitmap(Bitmap bitmap , int pixels) {
        final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        final 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);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawCircle(100,100, 90, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        bitmap.recycle();
        return output;
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_apploud, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_addnew) {
            Intent i;
            i=new Intent(Profile.this,ApplaudSomeone.class);
            startActivity(i);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Solution 48 - Android

Try this

Bitmap finalBitmap;
		if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
			finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
					false);
		else
			finalBitmap = bitmap;
		Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
				finalBitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
				finalBitmap.getHeight());

		paint.setAntiAlias(true);
		paint.setFilterBitmap(true);
		paint.setDither(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(Color.parseColor("#BAB399"));
		canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f,
				finalBitmap.getHeight() / 2 + 0.7f,
				finalBitmap.getWidth() / 2 + 0.1f, paint);
		paint.setXfermode(new PorterDuffXfermode(
				android.graphics.PorterDuff.Mode.SRC_IN));
		canvas.drawBitmap(finalBitmap, rect, rect, paint);

		return output;

Solution 49 - Android

    /**
 * Background Async task to load user profile picture from url
 */
private class LoadProfileImage extends AsyncTask<String, Void, RoundedBitmapDrawable> {
    ImageView profileImageView;

    public LoadProfileImage(ImageView profileImageView) {
        this.profileImageView = profileImageView;
    }

    protected RoundedBitmapDrawable doInBackground(String... urls) {
        String photoUrl = urls[0];
        RoundedBitmapDrawable profileRoundedDrawable = null;
        try {
            InputStream inputStream = new java.net.URL(photoUrl).openStream();
            Resources res = getResources();

            profileRoundedDrawable = RoundedBitmapDrawableFactory.create(res, inputStream);
            profileRoundedDrawable.setCircular(true);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return profileRoundedDrawable;
    }

    protected void onPostExecute(RoundedBitmapDrawable result) {
        profileImageView.setImageDrawable(result);
    }
}

Solution 50 - Android

While the first two answers work, I wish to describe a bit more. Say, you have an activity or a fragment where your ImageView lies. You wish to draw an image and scale it proportionally. Then you should write in onCreate or onCreateView the following:

LinearLayout rootLayout = (LinearLayout) findViewById(R.id.rootLayout);
ImageView image = (ImageView) findViewById(R.id.image);
// Wait till an activity is visible and image can be measured.
rootLayout.post(new Runnable() {
	@Override
	public void run() {
		// Setting ImageView height with aspect ratio.
		Drawable drawable = ContextCompat.getDrawable(getActivity(), R.drawable.your_image);
		int height = getImageViewHeight(drawable, image);

		// Rounding image corners.
		float radius = getResources().getDimension(R.dimen.your_radius_in_dp);
		Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
		Bitmap result = getRoundedBitmap(bitmap, image.getWidth(), height, radius);
		image.setImageBitmap(result);
	}
});

Where setting a new image height is:

public static int getImageViewHeight(Drawable drawable, ImageView imageView) {
    imageView.setImageDrawable(drawable);
    int width = drawable.getIntrinsicWidth();
    int height = 0;
    if (width > 0) {
        height = (drawable.getIntrinsicHeight() * imageView.getWidth()) / width;
        imageView.getLayoutParams().height = height;
        imageView.requestLayout();
    }
    return height;
}

Then you should write a method to scale an image and round its corners. Here width and height are new dimensions of a bitmap (smaller or larger). In the following example I round only two top corners.

private Bitmap getRoundedBitmap(Bitmap bitmap, int width, int height, float radius) {
    // Create scaled bitmap.
	Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
	BitmapShader shader = new BitmapShader(scaledBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

	Paint paint = new Paint();
	paint.setAntiAlias(true);
	paint.setShader(shader);

	Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
	Canvas canvas = new Canvas(result);
	// First make all corners round.
	canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paint);
	// Then draw bottom rectangle.
	canvas.drawRect(0, height - radius, radius, height, paint);
	canvas.drawRect(width - radius, height - radius, width, height, paint);
	return result;
}

Solution 51 - Android

here my solution:

<com.myproject.ui.RadiusCornerImageView
        android:id="@+id/imageViewPhoto"
        android:layout_width="160dp"
        android:layout_height="160dp"
        app:corner_radius_dp="5"
        app:corner_radius_position="top"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

And in java code:

public class RadiusCornerImageView extends android.support.v7.widget.AppCompatImageView {
    private int cornerRadiusDP = 0; // dp
    private int corner_radius_position;

    public RadiusCornerImageView(Context context) {
        super(context);
    }

    public RadiusCornerImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RadiusCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RadiusCornerImageView, 0, 0);
        try {
            cornerRadiusDP = typeArray.getInt(R.styleable.RadiusCornerImageView_corner_radius_dp, 0);
            corner_radius_position = typeArray.getInteger(R.styleable.RadiusCornerImageView_corner_radius_position, 0);
        } finally {
            typeArray.recycle();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float radiusPx = AndroidUtil.dpToPx(getContext(), cornerRadiusDP);
        Path clipPath = new Path();
        RectF rect = null;
        if (corner_radius_position == 0) { // all
            // round corners on all 4 angles
            rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        } else if (corner_radius_position == 1) {
            // round corners only on top left and top right
            rect = new RectF(0, 0, this.getWidth(), this.getHeight() + radiusPx);

    } else {
        throw new IllegalArgumentException("Unknown corner_radius_position = " + corner_radius_position);
    }
    clipPath.addRoundRect(rect, radiusPx, radiusPx, Path.Direction.CW);
    canvas.clipPath(clipPath);
    super.onDraw(canvas);
 }
}

Solution 52 - Android

I used a Path to draw only corners on the image Canvas. (I needed solution with no bitmap memory allocation)

@Override
protected void onDraw(final Canvas canvas) {
    super.onDraw(canvas);

    if (!hasRoundedCorners()) return;

    mPaint.setStyle(Paint.Style.FILL);
    mPaint.setStrokeWidth(0);

    Path path = new Path();
    path.setFillType(Path.FillType.INVERSE_WINDING);
    path.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRadius, mRadius, Path.Direction.CCW);
    canvas.drawPath(path, mPaint);
}

Notice that you should not allocate any new object in onDraw method. This code is a proof of concept and should not be used like this in product code

See more: https://medium.com/@przemek.materna/rounded-image-view-no-bitmap-reallocation-11a8b163484d

Solution 53 - Android

For me the following solution seems to be the most elegant:

ImageView roundedImageView = new ImageView (getContext());
roundedImageView.setClipToOutline(true);
Bitmap bitmap = AppUtil.decodeSampledBitmapFromResource(new File(valueListItemsView.getImagePath()), width, height);
roundedImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
roundedImageView.setImageBitmap(bitmap);
roundedImageView.setBackgroundResource(R.drawable.rounded_corner);

and the code for the rounded_corner.xml drawable is :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorAccent" />
    <corners android:radius="24dp" />
</shape>

Solution 54 - Android

Kotlin Version:

@GlideExtension
object GamersGeekGlideExtension {

    @NonNull
    @JvmStatic
    @GlideOption
    fun roundedCorners(options: BaseRequestOptions<*>, context: Context, cornerRadius: Int): BaseRequestOptions<*> {
        val px =
            (cornerRadius * (context.resources.displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)).roundToInt()
        return options.transforms(RoundedCorners(px))
    }
}

Note: Glide Extensions now requires BaseRequestOptions instead of RequestOptions. Also, its the same function as @Sir Codesalot answer just converted in kotlin.

Solution 55 - Android

It can be easily done with the following shape. Add it as a src to your image. If you want to remove the border simply add your background color to the border ;-)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/img_area_one"
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />

    <item>
        <shape
            android:padding="10dp"
            android:shape="rectangle">
            <corners
                android:topLeftRadius="8dp"
                android:topRightRadius="8dp"
                />
            <stroke
                android:width="5dp"
                android:color="@color/white" />
        </shape>
    </item>
</layer-list> 

Solution 56 - Android

If you don't want to border affects the image, use this class. Unfortunately, I didn't find any approach to draw a transparent area on the canvas came to onDraw(). So, here is created a new bitmap and it's drawn on a real canvas.

The view is useful if you want to make a disappearing border. If you set borderWidth to 0, the border will disappear and the image remains with rounder corners exactly like the border was. I.e. it looks like the border is drawn exactly by the image edges.

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.RectF
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView


class RoundedImageViewWithBorder @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0) : AppCompatImageView(context, attrs, defStyleAttr) {

    var borderColor: Int = 0
        set(value) {
            invalidate()
            field = value
        }
    var borderWidth: Int = 0
        set(value) {
            invalidate()
            field = value
        }
    var cornerRadius: Float = 0f
        set(value) {
            invalidate()
            field = value
        }

    private var bitmapForDraw: Bitmap? = null
    private var canvasForDraw: Canvas? = null
    private val transparentPaint = Paint().apply {
        isAntiAlias = true
        color = Color.TRANSPARENT
        style = Paint.Style.STROKE
        xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
    }

    private val borderPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.STROKE
    }

    private val transparentAreaRect = RectF()
    private val borderRect = RectF()

    init {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageViewWithBorder)

        try {
            borderWidth = typedArray.getDimensionPixelSize(R.styleable.RoundedImageViewWithBorder_border_width, 0)
            borderColor = typedArray.getColor(R.styleable.RoundedImageViewWithBorder_border_color, 0)
            cornerRadius = typedArray.getDimensionPixelSize(R.styleable.RoundedImageViewWithBorder_corner_radius, 0).toFloat()

        } finally {
            typedArray.recycle()
        }
    }

    @SuppressLint("CanvasSize", "DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        if (canvas.height <=0 || canvas.width <=0) {
            return
        }

        if (canvasForDraw?.height != canvas.height || canvasForDraw?.width != canvas.width) {
            val newBitmap = Bitmap.createBitmap(canvas.width, canvas.height, Bitmap.Config.ARGB_8888)
            bitmapForDraw = newBitmap
            canvasForDraw = Canvas(newBitmap)
        }
        
        bitmapForDraw?.eraseColor(Color.TRANSPARENT)

        // Draw existing content
        super.onDraw(canvasForDraw)

        if (borderWidth > 0) {
            canvasForDraw?.let { drawWithBorder(it) }
        } else {
            canvasForDraw?.let { drawWithoutBorder(it) }
        }

        // Draw everything on real canvas
        bitmapForDraw?.let { canvas.drawBitmap(it, 0f, 0f, null) }
    }

    private fun drawWithBorder(canvas: Canvas) {
        // Draw transparent area
        transparentPaint.strokeWidth = borderWidth.toFloat() * 4
        transparentAreaRect.apply {
            left = -borderWidth.toFloat() * 1.5f
            top = -borderWidth.toFloat() * 1.5f
            right = canvas.width.toFloat() + borderWidth.toFloat() * 1.5f
            bottom = canvas.height.toFloat() + borderWidth.toFloat() * 1.5f
        }
        canvasForDraw?.drawRoundRect(transparentAreaRect, borderWidth.toFloat() * 2 + cornerRadius, borderWidth.toFloat() * 2 + cornerRadius, transparentPaint)

        // Draw border
        borderPaint.color = borderColor
        borderPaint.strokeWidth = borderWidth.toFloat()
        borderRect.apply {
            left = borderWidth.toFloat() / 2
            top = borderWidth.toFloat() / 2
            right = canvas.width.toFloat() - borderWidth.toFloat() / 2
            bottom = canvas.height.toFloat() - borderWidth.toFloat() / 2
        }
        canvas.drawRoundRect(borderRect, cornerRadius - borderWidth.toFloat() / 2, cornerRadius - borderWidth.toFloat() / 2, borderPaint)
    }

    private fun drawWithoutBorder(canvas: Canvas) {
        // Draw transparent area
        transparentPaint.strokeWidth = cornerRadius * 4
        transparentAreaRect.apply {
            left = -cornerRadius * 2
            top = -cornerRadius * 2
            right = canvas.width.toFloat() + cornerRadius * 2
            bottom = canvas.height.toFloat() + cornerRadius * 2
        }
        canvasForDraw?.drawRoundRect(transparentAreaRect, cornerRadius * 3, cornerRadius * 3, transparentPaint)
    }

}

In values:

<declare-styleable name="RoundedImageViewWithBorder">
    <attr name="corner_radius" format="dimension|string" />
    <attr name="border_width" format="dimension|reference" />
    <attr name="border_color" format="color|reference" />
</declare-styleable>

Solution 57 - Android

You can use the new ShapableImageView provided in newer versions of Android Material library.

For this, you first need to add the below dependency in your app level build.gradle file

implementation 'com.google.android.material:material:<version>'

Also, make sure that this app level build.gradle file is having Google's Maven Repository google() as below

allprojects {
repositories {
  google()
  jcenter()
}

}

Now after this, you can refer this resource to implement the imageview of your desired type or shape.

Solution 58 - Android

I suggest using the Coil library for this scenario

> Coil is Kotlin-first and uses modern libraries including Coroutines, OkHttp, Okio, and AndroidX Lifecycles.

github link

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmichaelView Question on Stackoverflow
Solution 1 - AndroidGeorge Walters IIView Answer on Stackoverflow
Solution 2 - AndroidTaras VovkovychView Answer on Stackoverflow
Solution 3 - AndroidhungryghostView Answer on Stackoverflow
Solution 4 - Androidvinc3m1View Answer on Stackoverflow
Solution 5 - AndroidGabriele MariottiView Answer on Stackoverflow
Solution 6 - AndroidtyczjView Answer on Stackoverflow
Solution 7 - AndroidChirag MittalView Answer on Stackoverflow
Solution 8 - AndroidHiren PatelView Answer on Stackoverflow
Solution 9 - AndroidCaspar HarmerView Answer on Stackoverflow
Solution 10 - AndroidshaileshView Answer on Stackoverflow
Solution 11 - AndroidChristianView Answer on Stackoverflow
Solution 12 - AndroidDamjanView Answer on Stackoverflow
Solution 13 - AndroidSir CodesalotView Answer on Stackoverflow
Solution 14 - AndroidgrrigoreView Answer on Stackoverflow
Solution 15 - AndroiddeadfishView Answer on Stackoverflow
Solution 16 - AndroidVahidView Answer on Stackoverflow
Solution 17 - AndroidjigarView Answer on Stackoverflow
Solution 18 - AndroidMrSnowflakeView Answer on Stackoverflow
Solution 19 - AndroidsorrodosView Answer on Stackoverflow
Solution 20 - AndroidAlexView Answer on Stackoverflow
Solution 21 - Androidj7nn7kView Answer on Stackoverflow
Solution 22 - Androidus_davidView Answer on Stackoverflow
Solution 23 - AndroidMartin ZeitlerView Answer on Stackoverflow
Solution 24 - AndroidfishautumnView Answer on Stackoverflow
Solution 25 - AndroidDanny Remington - OMSView Answer on Stackoverflow
Solution 26 - AndroidAnirudhView Answer on Stackoverflow
Solution 27 - AndroidmkmView Answer on Stackoverflow
Solution 28 - AndroidAmir ZiaratiView Answer on Stackoverflow
Solution 29 - AndroidDeep PatelView Answer on Stackoverflow
Solution 30 - AndroidP A GosaiView Answer on Stackoverflow
Solution 31 - AndroidAndrewView Answer on Stackoverflow
Solution 32 - AndroidChitrangView Answer on Stackoverflow
Solution 33 - AndroiddgngulcanView Answer on Stackoverflow
Solution 34 - AndroidShiba DasView Answer on Stackoverflow
Solution 35 - AndroiducMediaView Answer on Stackoverflow
Solution 36 - AndroidrharveyView Answer on Stackoverflow
Solution 37 - AndroidIgorGanapolskyView Answer on Stackoverflow
Solution 38 - AndroidAkshay PaliwalView Answer on Stackoverflow
Solution 39 - AndroidmbonninView Answer on Stackoverflow
Solution 40 - AndroidAlex JoligView Answer on Stackoverflow
Solution 41 - AndroidBasiView Answer on Stackoverflow
Solution 42 - AndroidMilad MohamadiView Answer on Stackoverflow
Solution 43 - AndroidPrashant PaliwalView Answer on Stackoverflow
Solution 44 - AndroidRefine TshingilaView Answer on Stackoverflow
Solution 45 - AndroidPhil RingsmuthView Answer on Stackoverflow
Solution 46 - AndroidDroid_MechanicView Answer on Stackoverflow
Solution 47 - Androidkumar kundanView Answer on Stackoverflow
Solution 48 - AndroidBhavinkumar PatelView Answer on Stackoverflow
Solution 49 - AndroidNorberto BeziView Answer on Stackoverflow
Solution 50 - AndroidCoolMindView Answer on Stackoverflow
Solution 51 - AndroidAlexView Answer on Stackoverflow
Solution 52 - AndroidCililingView Answer on Stackoverflow
Solution 53 - AndroidaurelianrView Answer on Stackoverflow
Solution 54 - AndroidJunia MontanaView Answer on Stackoverflow
Solution 55 - AndroidKasun ThilinaView Answer on Stackoverflow
Solution 56 - AndroidFoxView Answer on Stackoverflow
Solution 57 - AndroidPrateek SharmaView Answer on Stackoverflow
Solution 58 - AndroidJavid SattarView Answer on Stackoverflow