9

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!

2 Answers2

2

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.

vinc3m1
  • 4,075
  • 1
  • 26
  • 23
  • This looks nice, and seems to be what I was looking for. I don't have any android to test it right now, so I'm not sure if I should mark this question as an answered – Alexandre de Champeaux Mar 27 '13 at 17:30
1

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)); 
Vivek Kumar Srivastava
  • 2,158
  • 1
  • 16
  • 23
  • Thanks for your answer. But as I said, I have already tried to round the corners of my image, but since I need a fluid size bitmap, this implies keeping a reference to the original one, and I would like to avoid this. Basically I want to round the corners of the view itself, as if I was using this solution : [link](http://stackoverflow.com/questions/1683185/android-listview-with-rounded-corners) – Alexandre de Champeaux Jun 20 '12 at 16:36
  • 1
    Okay @Alex see this [link](http://stackoverflow.com/questions/6539781/android-imageview-with-rounded-corners-not-working) – Vivek Kumar Srivastava Jun 21 '12 at 04:52