title: Cropping image in irregular shape in android not working proper
body: <p>Hi people I am using a <a href="https://github.com/coderush/FlexiCrop" rel="nofollow noreferrer">FlexiCrop </a>andtrying to crop image in irregular shape my code for activity is looks like this</p>
  
  <pre><code>public class CropActivity 
  extends Activity implements OnTouchListener {
      private Uri mImageCaptureUri;
      private ImageView drawImageView;
      private Bitmap sourceBitmap;
      private Path clipPath;
  
      private static final int PICK_FROM_FILE = 1;
      private static final int CAMERA_CAPTURE = 2;
  
      Bitmap bmp;
      Bitmap alteredBitmap;
      Canvas canvas;
      Paint paint;
      Matrix matrix;
      float downx = 0;
      float downy = 0;
      float upx = 0;
      float upy = 0;
  
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);     
          setContentView(R.layout.crop);
          final String [] items           = new String [] {"Take from camera", "Select from gallery"};                
          ArrayAdapter&lt;String&gt; adapter    = new ArrayAdapter&lt;String&gt; (this, android.R.layout.select_dialog_item,items);
          AlertDialog.Builder builder     = new AlertDialog.Builder(this);
  
          builder.setTitle("Select Image");
          builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
              public void onClick( DialogInterface dialog, int item ) { //pick from camera
                  if (item == 0) {
                      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 e){
                          e.printStackTrace();
                      } catch(Exception e) {
                          e.printStackTrace();
                      }
                  } else { //pick from file
                      Intent intent = new Intent();
                      intent.setType("image/*");
                      intent.setAction(Intent.ACTION_GET_CONTENT);
                      startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);
                  }
              }
          } );
  
          final AlertDialog dialog = builder.create();
  
          Button button   = (Button) findViewById(R.id.btn_crop);
          Button saveButton   = (Button) findViewById(R.id.btn_save);
          Button discardButton    = (Button) findViewById(R.id.btn_discard);
  
          drawImageView = (ImageView) findViewById(R.id.DrawImageView);
          drawImageView.setOnTouchListener(this);
  
          button.setOnClickListener(new View.OnClickListener() {  
              @Override
              public void onClick(View v) {
                  dialog.show();
              }
          });
  
          saveButton.setOnClickListener(new View.OnClickListener() {  
              @Override
              public void onClick(View v) {
                  try {
                      String path = Environment.getExternalStorageDirectory().toString();
                      OutputStream fOut = null;
                      File file = new File(path, String.valueOf(Math.round(Math.random()*100000))+".jpg");
                      fOut = new FileOutputStream(file);
  
                      alteredBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
                      fOut.flush();
                      fOut.close();
  
                      MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
                      AlertDialog.Builder builder     = new AlertDialog.Builder(StickersCreator.this);
                      builder.setMessage("Saved");
                      AlertDialog dialog = builder.create();
                      dialog.show();
  
                      //Now deleting the temporary file created on camera capture
                      File f = new File(mImageCaptureUri.getPath());            
                      if (f.exists()) {
                          f.delete();
                      }
  
                  } catch (Exception e) {
                         e.printStackTrace();
                  }
              }
          });
  
          discardButton.setOnClickListener(new View.OnClickListener() {   
              @Override
              public void onClick(View v) {
                  if (mImageCaptureUri != null) {
                      //Now deleting the temporary file created on camera capture
                      File f = new File(mImageCaptureUri.getPath());            
                      if (f.exists()) {
                          f.delete();
                      }
  
                      getContentResolver().delete(mImageCaptureUri, null, null );
                      mImageCaptureUri = null;
                      //resetting the image view
                      ImageView iv = (ImageView) findViewById(R.id.DrawImageView);
                      iv.setImageDrawable(null);
  
  
                  }
              }
          });
      }
  
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if (resultCode != RESULT_OK) return;
          switch (requestCode) {
  
              case PICK_FROM_FILE: 
                  mImageCaptureUri = data.getData();
                  doCrop();
                  break;
  
              case CAMERA_CAPTURE:
                  mImageCaptureUri = data.getData();
                  doCrop();
                  break;
          }
      }
      @Override
      public boolean onTouch(View v, MotionEvent event) {
          int action = event.getAction();
          switch (action) {
          case MotionEvent.ACTION_DOWN:
            downx = event.getX();
            downy = event.getY();
            clipPath = new Path();
            clipPath.moveTo(downx, downy);
            break;
          case MotionEvent.ACTION_MOVE:
            upx = event.getX();
            upy = event.getY();
            canvas.drawLine(downx, downy, upx, upy, paint);
            clipPath.lineTo(upx, upy);
            drawImageView.invalidate();
            downx = upx;
            downy = upy;
            break;
          case MotionEvent.ACTION_UP:
            upx = event.getX();
            upy = event.getY();
            canvas.drawLine(downx, downy, upx, upy, paint);
            clipPath.lineTo(upx, upy);
            drawImageView.invalidate();
            cropImageByPath();
            break;
          case MotionEvent.ACTION_CANCEL:
            break;
          default:
            break;
          }
          return true;
      }
  
      private void cropImageByPath() {
          //closing the path now.
          clipPath.close();
          //setting the fill type to inverse, so that the outer part of the selected path gets filled.
          clipPath.setFillType(FillType.INVERSE_WINDING);
          Paint xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
          xferPaint.setColor(Color.BLACK);
          canvas.drawPath(clipPath, xferPaint);
          xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
          canvas.drawBitmap(alteredBitmap, 0, 0, xferPaint);
      }
  
      private void doCrop() {
          try {
                  sourceBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), mImageCaptureUri);
                  BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
                  bmpFactoryOptions.inJustDecodeBounds = true;
                  bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                          mImageCaptureUri), null, bmpFactoryOptions);
                  bmpFactoryOptions.inJustDecodeBounds = false;
                  bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                          mImageCaptureUri), null, bmpFactoryOptions);
                  alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
                      .getHeight(), bmp.getConfig());
                  canvas = new Canvas(alteredBitmap);
                  paint = new Paint();
                  paint.setColor(Color.GREEN);
                  paint.setStrokeWidth(5);
                  matrix = new Matrix();
                  canvas.drawBitmap(bmp, matrix, paint);
                  //loading the image bitmap in image view
                  drawImageView.setImageBitmap(alteredBitmap);
                  //setting the touch listener
                  drawImageView.setOnTouchListener(this);
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
      }
  }
  </code></pre>
  
  <p>It is cropping image but when i draw shape for cropping shape drawing start from far away point from where i touched and draw shape it draw shape upside from i have touched the view please any on can suggest what is wrong i am doing here</p>
  
  <p><a href="https://i.stack.imgur.com/4mMGe.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4mMGe.jpg" alt="enter image description here"></a>
   firs is the original image  and on it when i draw a very big circle on key board it crops very far away from key board and very small circle second image 
  I darwed a circle on keyboard but it cropped from upside and also size of circle is very small</p>
  
  <p><a href="https://i.stack.imgur.com/J1g4j.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/J1g4j.jpg" alt="enter image description here"></a></p>