Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Antialiased rounded corners on Android ImageView [duplicate]

I am new to android dev, and I have been trying for a few hours now to add nice and smooth rounded corners to an ImageView, without success.

First thing I tried is simply to round corners of my images directly, but this implies changing the bitmap, and since I need to keep the raw ones, and those are pretty big, this is not really memory friendly. This would also cause other difficulties since my ImageView is fluid.

Second thing I tried to use is the clipPath method after subclassing my view. This works, but corners are aliased. I then tried adding a PaintFlagsDrawFilter to implement the aliasing, but this didn't worked. I'm using monodroid, and I was wondering this was supposed to work in Java.

Here is my code (C#):

public class MyImageView : ImageView
{
    private float[] roundedCorner;

    /**
     * Contains the rounded  corners for the view.
     * You can define one, four or height values.
     * This behaves as the css border-radius property
     * 
     * @see http://developer.android.com/reference/android/graphics/Path.html#addRoundRect(android.graphics.RectF, float[], android.graphics.Path.Direction)
     */
    public float[] RoundedCorners{
        get{
            return roundedCorner;
        }
        set{
            float[] finalValue = new float[8];
            int i=0;
            if(value.Length == 1){
                for(i=0; i<8;i++){
                    finalValue[i] = value[0];
                }
            }else if(value.Length == 4){
                for(i=0; i<4;i++){
                    finalValue[2*i] = value[i];
                    finalValue[2*i+1] = value[i];
                }
            }

            roundedCorner = finalValue;
        }
    }

    public SquareImageView (Context context) :
        base (context)
    {
        Initialize ();
    }

    public SquareImageView (Context context, IAttributeSet attrs) :
        base (context, attrs)
    {
        Initialize ();
    }

    private void Initialize ()
    {
        RoundedCorners = new float[]{0,0,0,0};
    }

    public override void Draw (Android.Graphics.Canvas canvas)
    {
        Path path = new Path();
        path.AddRoundRect(new RectF(0,0, Width,Height),RoundedCorners, Path.Direction.Cw);

        canvas.ClipPath(path);

        base.Draw (canvas);
    }

    /**
     *  try to add antialiasing.
             */
    protected override void DispatchDraw (Canvas canvas)
    {

        canvas.DrawFilter = new PaintFlagsDrawFilter((PaintFlags)1, PaintFlags.AntiAlias);
        base.DispatchDraw (canvas);
    }

}

Thanks for your help!

like image 708
Alexandre de Champeaux Avatar asked Jun 20 '12 01:06

Alexandre de Champeaux


2 Answers

I've created a RoundedImageView based off Romain Guy's example code that wraps this logic into an ImageView that you should be able to just use. It supports borders and antialiasing out of the box.

It's more efficient than other rounded corner examples because it doesn't create another copy of the bitmap, nor does it use clipPath which draws twice to the canvas.

like image 82
vinc3m1 Avatar answered Nov 19 '22 11:11

vinc3m1


use below code

public Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) 
    {
        Bitmap output = null;

        if(bitmap != null)
        {
            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;
    }

and call this method like

   imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 10)); 
like image 1
Vivek Kumar Srivastava Avatar answered Nov 19 '22 09:11

Vivek Kumar Srivastava