Search code examples
androidborderandroid-bitmap

Android circular border around circular image


I do this to get a circular ImageView, how can I add a circle border around it like this picture:

Screenshot of expected result

public static Bitmap getRoundedShape(Bitmap scaleBitmapImage,int width) {
    int targetWidth = width;
    int targetHeight = width;
    Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, 
            targetHeight,Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(targetBitmap);
    Path path = new Path();
    path.addCircle(((float) targetWidth - 1) / 2,
            ((float) targetHeight - 1) / 2,
            (Math.min(((float) targetWidth), 
            ((float) targetHeight)) / 2),
            Path.Direction.CCW);
    canvas.clipPath(path);
    Bitmap sourceBitmap = scaleBitmapImage;
    canvas.drawBitmap(sourceBitmap, 
            new Rect(0, 0, sourceBitmap.getWidth(),
            sourceBitmap.getHeight()), 
            new Rect(0, 0, targetWidth, targetHeight), null);
    return targetBitmap;
}

Solution

  • There is a very interesting post about this feature: http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/ It is written by Romain Guy (ex android team at Google).

    You can use something like this: This example create a circular bitmap, with around a white stroke. You can change it, adding a white stroke with a black line.

    public class CircleDrawable extends Drawable {
    
        private final BitmapShader mBitmapShader;
        private final Paint mPaint;
        private Paint mWhitePaint;
        int circleCenterX;
        int circleCenterY;
        int mRadus;
        private boolean mUseStroke = false;
        private int mStrokePadding = 0;
    
        public CircleDrawable(Bitmap bitmap) {
    
            mBitmapShader = new BitmapShader(bitmap,
                    Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setShader(mBitmapShader);
    
        }
    
        public CircleDrawable(Bitmap bitmap, boolean mUseStroke) {
            this(bitmap);
    
            if (mUseStroke) {
                this.mUseStroke = true;
                mStrokePadding = 4;
                mWhitePaint = new Paint();
                mWhitePaint.setStyle(Paint.Style.FILL_AND_STROKE);
                mWhitePaint.setStrokeWidth(0.75f);
                mWhitePaint.setColor(Color.WHITE);
            }
        }
    
        @Override
        protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            circleCenterX = bounds.width() / 2;
            circleCenterY = bounds.height() / 2;
    
            if (bounds.width() >= bounds.height())
                mRadus = bounds.width() / 2;
            else
                mRadus = bounds.height() / 2;
        }
    
        @Override
        public void draw(Canvas canvas) {
            if (mUseStroke) {
                canvas.drawCircle(circleCenterX, circleCenterY, mRadus, mWhitePaint);
            }
            canvas.drawCircle(circleCenterX, circleCenterY, mRadus - mStrokePadding, mPaint);
        }
    
        @Override
        public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
        }
    
        @Override
        public void setAlpha(int alpha) {
            mPaint.setAlpha(alpha);
        }
    
        @Override
        public void setColorFilter(ColorFilter cf) {
            mPaint.setColorFilter(cf);
        }
    
        public boolean ismUseStroke() {
            return mUseStroke;
        }
    
        public void setmUseStroke(boolean mUseStroke) {
            this.mUseStroke = mUseStroke;
        }
    
    }