Mask ImageView with round corner background

GrIsHu picture GrIsHu · Aug 30, 2013 · Viewed 90.6k times · Source

I am having a Custom ListView which contains an ImageView and TextView. Everything is working fine.

What I want is the image is displayed in list are in round corner. From the Webservice i get the images in rectangle shape. But i want to display it in Round corner ImageView as below.

enter image description here

Can anyone show me the way how can i mask the image in round corner?

I already tried by creating the drawable file as below and applied it as src in ImageView. But nothing working for me.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
   <item>
      <shape android:shape="oval" >
         <solid android:color="#FFFFFF" />
         <padding
            android:bottom="10dp"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp" />
         <corners android:radius="5dp" />
      </shape>
   </item>
   <item>
      <shape android:shape="oval" >
         <padding
            android:bottom="5dp"
            android:left="5dp"
            android:right="5dp"
            android:top="5dp" />
         <solid android:color="#FFFFFF" />
      </shape>
   </item>
</layer-list>

EDITED:

enter image description here

I have Applied below solution:

<FrameLayout
    android:id="@+id/imagemaskframe"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/op_ivpic"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        android:scaleType="fitXY" />

    <ImageView
        android:id="@+id/iv_mask_op"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:src="@drawable/imgmask" />

</FrameLayout>

Answer

sriramramani picture sriramramani · Aug 30, 2013

The best way is to do it in Canvas using PorterDuff operations and/or Shaders. Let's say your Bitmap is available and stored in mBitmap.

Option 1: Using Shaders.

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

    // Load the bitmap as a shader to the paint.
    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    final Shader shader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    paint.setShader(shader);

    // Draw a circle with the required radius.
    final float halfWidth = canvas.getWidth()/2;
    final float halfHeight = canvas.getHeight()/2;
    final float radius = Math.max(halfWidth, halfHeight);
    canvas.drawCircle(halfWidth, halfHeight, radius, paint);
}

Option 2: Using PorterDuff mode.

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

    // Create a circular path.
    final float halfWidth = canvas.getWidth()/2;
    final float halfHeight = canvas.getHeight()/2;
    final float radius = Math.max(halfWidth, halfHeight);
    final Path path = new Path();
    path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);

    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    canvas.drawPath(path, paint);
}

Note:

  1. It's not good to create objects inside onDraw() calls. Hence you should have your paint and shader initially somewhere else. This could probably be done when you set the image bitmap to the view.
  2. Canvas might need to be saved and restored when it is not backed by a hardware texture. The general ideas around it are not mentioned here.
  3. Remember to add setWillNotDraw(false); to the constructor.

Additional References:

  1. https://sriramramani.wordpress.com/2012/12/21/shaders/ has information on Shaders.
  2. http://mxr.mozilla.org/mozilla-central/source/mobile/android/base/ShapedButton.java uses Path to curved button in Firefox for Android.
  3. http://sriramramani.wordpress.com/2012/08/27/constructing-squishy-buttons/ has information on Canvas saving, restoring and special cases for pre-ICS.