Narendra Sorathiya
Narendra Sorathiya

Reputation: 3830

How to crop Bitmap?

I have retrevied Bitmap from fragment & I placed bitmap(decoded bytearray) in Imageview, I want to crop this bitmap

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fr_editcrop, container, false);


    cropphoto = (ImageView)view.findViewById(R.id.cropphoto);
    title = (TextView)view.findViewById(R.id.title);
    title.setText("Crop");

    crop = (Button)view.findViewById(R.id.crop);
    cancel = (Button)view.findViewById(R.id.cancel);

    tmp = getArguments().getString("PHOTO");

    byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
    bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
    cropphoto.setImageBitmap(bmp);

    Width = cropphoto.getWidth();
    Height = cropphoto.getHeight();

Upvotes: 4

Views: 6785

Answers (5)

Narendra Sorathiya
Narendra Sorathiya

Reputation: 3830

After a long time, i got such a solution that just Use Edmodo Library for Simple Crop your Bitmap...

Upvotes: -4

Rank Mayur
Rank Mayur

Reputation: 116

Used System Crop:

private void doCrop() {

    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setType("image/*");

    List<ResolveInfo> list = getPackageManager().queryIntentActivities(
            intent, 0);

    int size = list.size();

    if (size == 0) {
        Toast.makeText(this, "Can not find image crop app",
                Toast.LENGTH_SHORT).show();
        return;
    } else {
        intent.setData(mImageCaptureUri);

        intent.putExtra("outputX", 180);
        intent.putExtra("outputY", 310);
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1.5f);
        intent.putExtra("crop", false);
        // intent.putExtra("scale", false);
        intent.putExtra("return-data", true);
        Intent i = new Intent(intent);
        ResolveInfo res = list.get(0);

        i.setComponent(new ComponentName(res.activityInfo.packageName,
                res.activityInfo.name));

        startActivityForResult(i, CROP_FROM_CAMERA);            
    }
}

Upvotes: 0

King of Masses
King of Masses

Reputation: 18765

instead of using the default "com.android.camera.action.CROP". i just want to share this piece of code that will provide the custom crop or freehand crop activity for image view. hopefully it will help you guys.

First you need to create a class like CropView

public class CropView extends ImageView {

Paint paint = new Paint();
private int initial_size = 300;
private static Point leftTop, rightBottom, center, previous;

private static final int DRAG= 0;
private static final int LEFT= 1;
private static final int TOP= 2;
private static final int RIGHT= 3;
private static final int BOTTOM= 4;

private int imageScaledWidth,imageScaledHeight;
// Adding parent class constructors   
public CropView(Context context) {
   super(context);
   initCropView();
 }

 public CropView(Context context, AttributeSet attrs) {
   super(context, attrs, 0);
   initCropView();
 }

 public CropView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  initCropView();
 }

 @Override
 protected void onDraw(Canvas canvas)
 {
   super.onDraw(canvas);
   if(leftTop.equals(0, 0))
      resetPoints();
  canvas.drawRect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, paint);
  }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  int eventaction = event.getAction();
  switch (eventaction) { 
      case MotionEvent.ACTION_DOWN:
          previous.set((int)event.getX(), (int)event.getY());
          break; 
     case MotionEvent.ACTION_MOVE: 
         if(isActionInsideRectangle(event.getX(), event.getY())) {
             adjustRectangle((int)event.getX(), (int)event.getY());
             invalidate(); // redraw rectangle
             previous.set((int)event.getX(), (int)event.getY());
         }
         break; 
     case MotionEvent.ACTION_UP: 
         previous = new Point();
         break;
 }         
  return true;
 }

 private void initCropView() {
  paint.setColor(Color.YELLOW);
 paint.setStyle(Style.STROKE);
 paint.setStrokeWidth(5);  
 leftTop = new Point();
 rightBottom = new Point();
 center = new Point();
 previous = new Point();
 }

public void resetPoints() {
   center.set(getWidth()/2, getHeight()/2);
   leftTop.set((getWidth()-initial_size)/2,(getHeight()-initial_size)/2);
   rightBottom.set(leftTop.x+initial_size, leftTop.y+initial_size);
 }

 private static boolean isActionInsideRectangle(float x, float y) {
  int buffer = 10;
  return (x>=(leftTop.x-buffer)&&x<=(rightBottom.x+buffer)&& y>=(leftTop.y-buffer)&&y<=(rightBottom.y+buffer))?true:false;
 }

 private boolean isInImageRange(PointF point) {
  // Get image matrix values and place them in an array
  float[] f = new float[9];
 getImageMatrix().getValues(f);

 // Calculate the scaled dimensions
  imageScaledWidth = Math.round(getDrawable().getIntrinsicWidth() * f[Matrix.MSCALE_X]);
  imageScaledHeight = Math.round(getDrawable().getIntrinsicHeight() * f[Matrix.MSCALE_Y]);

  return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false;
}

 private void adjustRectangle(int x, int y) {
  int movement;
  switch(getAffectedSide(x,y)) {
      case LEFT:
         movement = x-leftTop.x;
         if(isInImageRange(new  PointF(leftTop.x+movement,leftTop.y+movement)))
            leftTop.set(leftTop.x+movement,leftTop.y+movement);
        break;
      case TOP:
        movement = y-leftTop.y;
        if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement)))
            leftTop.set(leftTop.x+movement,leftTop.y+movement);
        break;
      case RIGHT:
        movement = x-rightBottom.x;
        if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
            rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
        break;
     case BOTTOM:
        movement = y-rightBottom.y;
        if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
            rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
        break;      
     case DRAG:
        movement = x-previous.x;
        int movementY = y-previous.y;
        if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movementY)) && isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movementY))) {
            leftTop.set(leftTop.x+movement,leftTop.y+movementY);
              rightBottom.set(rightBottom.x+movement,rightBottom.y+movementY);
        }
        break;
  }
}

  private static int getAffectedSide(float x, float y) {
   int buffer = 10;
   if(x>=(leftTop.x-buffer)&&x<=(leftTop.x+buffer))
    return LEFT;
   else if(y>=(leftTop.y-buffer)&&y<=(leftTop.y+buffer))
    return TOP;
   else if(x>=(rightBottom.x-buffer)&&x<=(rightBottom.x+buffer))
    return RIGHT;
   else if(y>=(rightBottom.y-buffer)&&y<=(rightBottom.y+buffer))
    return BOTTOM;
    else
     return DRAG;
   }

   public byte[] getCroppedImage() {
   BitmapDrawable drawable = (BitmapDrawable)getDrawable();
   float x = leftTop.x-center.x+(drawable.getBitmap().getWidth()/2);
   float y = leftTop.y-center.y+(drawable.getBitmap().getHeight()/2);
   Bitmap cropped = Bitmap.createBitmap(drawable.getBitmap(),(int)x,(int)y,(int)rightBottom.x-(int)leftTop.x,(int)rightBottom.y-(int)leftTop.y);
 ByteArrayOutputStream stream = new ByteArrayOutputStream();
 cropped.compress(Bitmap.CompressFormat.PNG, 100, stream);
  return stream.toByteArray();
  }
 }

What i did was, i extended the ImageView and added Cropping powers. It is pretty easy to use. Once the class is saved, just use it in the layout like this.

<"your package name".CropView
 android:id="@+id/image_preview"
 android:layout_width="fill_parent"
 android:layout_height="match_parent" />

And call this Crop View in your activity like below

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);

 setContentView(R.layout.crop_layout);


 myCropView = new CropView(this);

  tmp = getArguments().getString("PHOTO");

   byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
   bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
   myCropView.setImageBitmap(bmp);

}

Thats it! Hope it helps! If you encounter any problem, please feel free to ask :)

Upvotes: 0

Elesh Baraiya
Elesh Baraiya

Reputation: 388

use this method.

private void doCrop() {
    final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();

    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setType("image/*");

    List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities(intent, 0);

    int size = list.size();

    if (size == 0) {
        Toast.makeText(getActivity(), "Can not find image crop app", Toast.LENGTH_SHORT).show();

        return;
    } else {

        intent.setData(Uri.fromFile(new File(mainActivity.mCommonMethod.getAppPath() + "/profile.png")));

        intent.putExtra("outputX", 256);
        intent.putExtra("outputY", 256);
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", true);

        if (size == 1) {
            Intent i = new Intent(intent);
            ResolveInfo res = list.get(0);
            i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
            startActivityForResult(i, CROP_FROM_CAMERA);
        } else {
            for (ResolveInfo res : list) {
                final CropOption co = new CropOption();

                co.title = getActivity().getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
                co.icon = getActivity().getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
                co.appIntent = new Intent(intent);
                co.appIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                cropOptions.add(co);
            }

            CropOptionAdapter adapter = new CropOptionAdapter(getActivity().getApplicationContext(), cropOptions);

            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Choose Crop App");
            builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int item) {
                    startActivityForResult(cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
                }
            });

            builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {

                    if (mImageCaptureUri != null) {
                        getActivity().getContentResolver().delete(mImageCaptureUri, null, null);
                        // mImageCaptureUri = null;
                        try {
                            bitmap = mainActivity.mCommonMethod.resizeBitmap(bitmap);
                            bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), mImageCaptureUri);
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            });

            AlertDialog alert = builder.create();

            alert.show();
        }
    }
}

Upvotes: 0

Call Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)

See reference.

Upvotes: 7

Related Questions