21 Aug 2013

Crop image in circular shape in android

Hello Friends,

Today i am sharing  cropping an image and convert it into circular shape. Following Class will helps you to convert an image into circular shape.



There is two method i am posting here for cropping rounded images.


import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;

public class GraphicsUtil 
{ 
 public Bitmap getCircleBitmap(Bitmap bitmap, int pixels) {
  Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
    bitmap.getHeight(), Bitmap.Config.ARGB_8888);
  Canvas canvas = new Canvas(output);

  final int color = 0xffff0000;
  final Paint paint = new Paint();
  final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
  final RectF rectF = new RectF(rect);

  paint.setAntiAlias(true);
  paint.setDither(true);
  paint.setFilterBitmap(true);
  canvas.drawARGB(0, 0, 0, 0);
  paint.setColor(color);
  canvas.drawOval(rectF, paint);

  paint.setColor(Color.BLUE);
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth((float) 4);
  paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
  canvas.drawBitmap(bitmap, rect, rect, paint);

  return output;
 }

 public Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
  int targetWidth = 125;
  int targetHeight = 125;
  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;
 }

}

MainActivity.Class
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener 
{

 // keep track of camera capture intent
 final int CAMERA_CAPTURE = 1;
 // keep track of cropping intent
 final int PIC_CROP = 2;
 // captured picture uri
 private Uri picUri;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) 
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  // retrieve a reference to the UI button
  Button captureBtn = (Button) findViewById(R.id.capture_btn);
  // handle button clicks
  captureBtn.setOnClickListener(this);
 }

 /**
  * Click method to handle user pressing button to launch camera
  */
 public void onClick(View v) 
 {
  if (v.getId() == R.id.capture_btn) 
  {
   try 
   {
    // use standard intent to capture an image
    Intent captureIntent = new Intent(
      MediaStore.ACTION_IMAGE_CAPTURE);
    // we will handle the returned data in onActivityResult
    startActivityForResult(captureIntent, CAMERA_CAPTURE);
   }
   catch (ActivityNotFoundException anfe) 
   {
    // display an error message
    String errorMessage = "Whoops - your device doesn't support capturing images!";
    Toast toast = Toast.makeText(this, errorMessage,Toast.LENGTH_SHORT);
    toast.show();
   }
  }
 }

 /**
  * Handle user returning from both capturing and cropping the image
  */
 protected void onActivityResult(int requestCode, int resultCode, Intent data)
 {
  if (resultCode == RESULT_OK) 
  {
   // user is returning from capturing an image using the camera
   if (requestCode == CAMERA_CAPTURE) 
   {
    // get the Uri for the captured image
    picUri = data.getData();
    // carry out the crop operation
    performCrop();
   }
   // user is returning from cropping the image
   else if (requestCode == PIC_CROP) 
   {
    // get the returned data
    Bundle extras = data.getExtras();
    // get the cropped bitmap
    Bitmap thePic = extras.getParcelable("data");
    // retrieve a reference to the ImageView
    ImageView picView = (ImageView) findViewById(R.id.picture);
    // display the returned cropped image

    GraphicsUtil graphicUtil = new GraphicsUtil();
    //picView.setImageBitmap(graphicUtil.getRoundedShape(thePic));
    picView.setImageBitmap(graphicUtil.getCircleBitmap(thePic, 16));
   }
  }
 }

 /**
  * Helper method to carry out crop operation
  */
 private void performCrop() 
 {
  // take care of exceptions
  try {
   // call the standard crop action intent (the user device may not
   // support it)
   Intent cropIntent = new Intent("com.android.camera.action.CROP");
   // indicate image type and Uri
   cropIntent.setDataAndType(picUri, "image/*");
   // set crop properties
   cropIntent.putExtra("crop", "true");
   // indicate aspect of desired crop
   cropIntent.putExtra("aspectX", 1);
   cropIntent.putExtra("aspectY", 1);
   // indicate output X and Y
   cropIntent.putExtra("outputX", 256);
   cropIntent.putExtra("outputY", 256);
   // retrieve data on return
   cropIntent.putExtra("return-data", true);
   // start the activity - we handle returning in onActivityResult
   startActivityForResult(cropIntent, PIC_CROP);
  }
  // respond to users whose devices do not support the crop action
  catch (ActivityNotFoundException anfe) {
   // display an error message
   String errorMessage = "Whoops - your device doesn't support the crop action!";
   Toast toast = Toast
     .makeText(this, errorMessage, Toast.LENGTH_SHORT);
   toast.show();
  }
 }
}

More reference link

I will be happy if you will provide your feedback or follow this blog. Any suggestion and help will be appreciated.
Thank you :)

10 comments:

  1. This code really works. Something I was looking for to use in my app. Thankyou so very much for posting this. Great post!!

    ReplyDelete
  2. Hello ! Thank you for this guide.

    However, what is the difference between :
    public Bitmap getCircleBitmap(Bitmap bitmap, int pixels) and
    public Bitmap getRoundedShape(Bitmap scaleBitmapImage)

    I am looking to crop profile pictures from facebook and twitter users into circular shape.
    How can I make sure that all cropped pictures in circular shape will have the same size depending on the original bitmap ?
    Because some time the original bitmap can be bigger or smaller ... how to handle ?

    I am then displaying the cropped pictures in a ListView. That's why I need the circular shapes to be the same size altogether.

    Thank you !

    ReplyDelete
    Replies
    1. Thank for your feedback,

      you can do that by using universal loader.

      here is some code to make round shape images.
      int rounded_value = 120;

      DisplayImageOptions options = new DisplayImageOptions.Builder()
      .cacheInMemory(true)
      .cacheOnDisc(true)
      .displayer(new RoundedBitmapDisplayer(rounded_value))
      .build();

      ImageLoader.getInstance().displayImage(strUrl1, imgThumb1,options);

      Universal Loader: https://github.com/nostra13/Android-Universal-Image-Loader

      Delete
  3. hai, this is awesome tutorial, ive tried on my samsung tablet it was work. it wasnt happen on my asus tablet. after i took a picture with asus,i cant find the picture on image gallery, i mean, after i took the picture, it doesnt save to the storage.
    can you help me please ?
    thanks before

    ReplyDelete
    Replies
    1. Hello

      Please visit

      http://www.hasmukhbhadani.com/search/label/Get%20image%20from%20Camera%20And%20gallery%20and%20display%20in%20Imageview%20Android.

      Delete
    2. sorry but, i run the code from http://www.hasmukhbhadani.com/search/label/Get%20image%20from%20Camera%20And%20gallery%20and%20display%20in%20Imageview%20Android.

      it was able to take a picture from the camera and show the result. but it wasnt save the result to image gallery on my asus fonepad 7.
      before this one, i tried with my samsung galaxy tab and it run properly.
      i dont know what to do
      thanks

      Delete
  4. I'm on the fence about this, while more customization is good, I have a feeling this is a "in-progress" update, it just feels incomplete and half-way there.
    We use badge layout for apps on design approvals (visual projects), so the image being displayed is important. Old layout "feels like" it had larger images,
    maybe because the images were cropped more loosely so it's easier to tell which project it was at quick glance. Now the image is cropped closer, making it
    harder to scan thru at quick glance. I find myself needing to click into the project more often than usual. Which makes the whole user experience less
    efficient.
    I have a couple suggestions that might make it work better:
    1. Increase the height of the window the cover image is being displayed.
    2. Let us to choose which image to be displayed as "cover" (like how Pinterest handles cover images of each board, was hoping for this for a long time)
    3. Let us adjust which part of the image to show and how tight or loose the crop is (with a fixed window, let us move the image around and maybe enlarge or
    shrink it to control what shows thru the window. Pinterest does a limited form of this, which is very useful in making the cover image relevant)
    4. Allow Cover Image to be ordered in different hierarchy (currently every element can be ordered differently except the Cover Image, it seems to be stuck
    in the 2nd spot, would like the option to set it on another spot in the layout. This one seems like an easy fix, since you guys allow that for every other
    element already)

    ReplyDelete
  5. I'm on the fence about this, while more customization is good, I have a feeling this is a "in-progress" update, it just feels incomplete and half-way there.
    We use badge layout for apps on design approvals (visual projects), so the image being displayed is important. Old layout "feels like" it had larger images,
    maybe because the images were cropped more loosely so it's easier to tell which project it was at quick glance. Now the image is cropped closer, making it
    harder to scan thru at quick glance. I find myself needing to click into the project more often than usual. Which makes the whole user experience less
    efficient.
    I have a couple suggestions that might make it work better:
    1. Increase the height of the window the cover image is being displayed.
    2. Let us to choose which image to be displayed as "cover" (like how Pinterest handles cover images of each board, was hoping for this for a long time)
    3. Let us adjust which part of the image to show and how tight or loose the crop is (with a fixed window, let us move the image around and maybe enlarge or
    shrink it to control what shows thru the window. Pinterest does a limited form of this, which is very useful in making the cover image relevant)
    4. Allow Cover Image to be ordered in different hierarchy (currently every element can be ordered differently except the Cover Image, it seems to be stuck
    in the 2nd spot, would like the option to set it on another spot in the layout. This one seems like an easy fix, since you guys allow that for every other
    element already)

    ReplyDelete