Friday 6 June 2014

HOW TO CROP IMAGE VIEW AS CIRCLE / ROUND IN ANDROID


In this tutorial we will make round image for better user experience.



Download Source Code Download
  1. Create New Project New->Android Application Project.
  2. Create New Class file Right Click on package->New->Class. Name it as RoundImage.java
  3. Copy the below code in RoundImage.java

RoundImage.java


import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

public class RoundImage extends Drawable {
      private final Bitmap mBitmap;
      private final Paint mPaint;
      private final RectF mRectF;
      private final int mBitmapWidth;
      private final int mBitmapHeight;

      public RoundImage(Bitmap bitmap) {
            mBitmap = bitmap;
            mRectF = new RectF();
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mPaint.setShader(shader);

            mBitmapWidth = mBitmap.getWidth();
            mBitmapHeight = mBitmap.getHeight();
      }

      @Override
      public void draw(Canvas canvas) {
            canvas.drawOval(mRectF, mPaint);
      }

      @Override
      protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            mRectF.set(bounds);
      }

      @Override
      public void setAlpha(int alpha) {
            if (mPaint.getAlpha() != alpha) {
                  mPaint.setAlpha(alpha);
                  invalidateSelf();
            }
      }

      @Override
      public void setColorFilter(ColorFilter cf) {
            mPaint.setColorFilter(cf);
      }

      @Override
      public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
      }

      @Override
      public int getIntrinsicWidth() {
            return mBitmapWidth;
      }

      @Override
      public int getIntrinsicHeight() {
            return mBitmapHeight;
      }

      public void setAntiAlias(boolean aa) {
            mPaint.setAntiAlias(aa);
            invalidateSelf();
      }

      @Override
      public void setFilterBitmap(boolean filter) {
            mPaint.setFilterBitmap(filter);
            invalidateSelf();
      }

      @Override
      public void setDither(boolean dither) {
            mPaint.setDither(dither);
            invalidateSelf();
      }

      public Bitmap getBitmap() {
            return mBitmap;
      }

}

Now your Project Hierarchy looks like this.
Project Hierarchy

Now open the activity_main.xml and pick up ImageView.

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:layout_gravity="center"
        android:src="@drawable/image" />

</LinearLayout>


And finally its time to show the rounded image , for that update the MainActivity.java file

MainActivity.java


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import com.tutorialsface.roundimage.R;

public class MainActivity extends Activity {

      ImageView imageView1;
      RoundImage roundedImage;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            imageView1 = (ImageView) findViewById(R.id.imageView1);
            Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.image);
            roundedImage = new RoundImage(bm);
            imageView1.setImageDrawable(roundedImage);
      }
}

Now run the project and you will see the Circular Image.
Note:- This code works for all images which have proper height and width, like 100x100, 200x200.

28 comments:

  1. Replies
    1. it's ok.....but isn't have something wrong error?

      Delete
  2. thank's for the tutorial .we are waiting a tutrial about GCM

    ReplyDelete
  3. have you copied this code from this website http://evel.io/2013/07/21/rounded-avatars-in-android/ ,it does not work well,after get image from Gallery or Camera,it shows oval image,not the complete circle image,I want a cirlce Image shape

    ReplyDelete
    Replies
    1. No I didn't copied it from this site, but found it from somewhere else. Your image should be proportionate, means 100x100 or 200x200

      Delete
    2. Is there a way to overcome this restriction?
      To get a center-cropped imageView that's also circular, yet also avoid creating a new bitmap?

      Delete
    3. You fix it by return the minimum of width and height in two method:
      @Override
      public int getIntrinsicWidth() {
      return mBitmapWidth < mBitmapHeight ? mBitmapWidth:mBitmapHeight ;
      }

      @Override
      public int getIntrinsicHeight() {
      return mBitmapHeight < mBitmapWidth ? mBitmapHeight: mBitmapWidth;
      }

      Delete
  4. thanks, you made my day!
    is it possible to add a border?

    ReplyDelete
    Replies
    1. https://github.com/Pkmmte/CircularImageView

      Delete
  5. Thanks ..I tried the same over another imageview .. its not showing .. your reply will be helpful

    ReplyDelete
  6. Thanks. It run in imageview.
    How to crop with image(icon) in menu item? Help me!

    ReplyDelete
  7. Thanks man... Your Tutorials are clear & easy to understand !!

    ReplyDelete
  8. If original image is not square in shape? Can I adapt this somehow?

    ReplyDelete
    Replies
    1. Hi, this is my idea:
      @Override
      public int getIntrinsicWidth() {
      return mBitmapWidth < mBitmapHeight ? mBitmapWidth:mBitmapHeight ;
      }

      @Override
      public int getIntrinsicHeight() {
      return mBitmapHeight < mBitmapWidth ? mBitmapHeight: mBitmapWidth;
      }

      You just return the minimum of width and height. It make for you a square.

      Delete
  9. Actually I want to capture an image and then set it to be as a circular Image View but by applying this code I am getting an Oval shaped Image. So can you guide me how to resolve this issue

    ReplyDelete
    Replies
    1. Replace the following code in RoundImage class.

      @Override
      public int getIntrinsicWidth() {
      return mBitmapWidth < mBitmapHeight ? mBitmapWidth:mBitmapHeight ;
      }

      @Override
      public int getIntrinsicHeight() {
      return mBitmapHeight < mBitmapWidth ? mBitmapHeight: mBitmapWidth;
      }

      Delete
  10. how to load image from url in circular imagview??

    ReplyDelete
  11. hey i am using android studio and this cod is not working in this...please update the latest code

    ReplyDelete
  12. Fantastic job man M very thank Full to you M very about this and you solve my problem Thannkyou soo
    much

    ReplyDelete