private void loadInput() {
    Intent intent = getIntent();
    Bundle extras = intent.getExtras();

    if (extras != null) {
      aspectX = extras.getInt(Crop.Extra.ASPECT_X);
      aspectY = extras.getInt(Crop.Extra.ASPECT_Y);
      maxX = extras.getInt(Crop.Extra.MAX_X);
      maxY = extras.getInt(Crop.Extra.MAX_Y);
      saveUri = extras.getParcelable(MediaStore.EXTRA_OUTPUT);
    }

    sourceUri = intent.getData();
    if (sourceUri != null) {
      exifRotation =
          CropUtil.getExifRotation(CropUtil.getFromMediaUri(this, getContentResolver(), sourceUri));

      InputStream is = null;
      try {
        sampleSize = calculateBitmapSampleSize(sourceUri);
        is = getContentResolver().openInputStream(sourceUri);
        BitmapFactory.Options option = new BitmapFactory.Options();
        option.inSampleSize = sampleSize;
        rotateBitmap = new RotateBitmap(BitmapFactory.decodeStream(is, null, option), exifRotation);
      } catch (IOException e) {
        Log.e("Error reading image: " + e.getMessage(), e);
        setResultException(e);
      } catch (OutOfMemoryError e) {
        Log.e("OOM reading image: " + e.getMessage(), e);
        setResultException(e);
      } finally {
        CropUtil.closeSilently(is);
      }
    }
  }
  private void saveOutput(Bitmap croppedImage) {
    if (saveUri != null) {
      OutputStream outputStream = null;
      try {
        outputStream = getContentResolver().openOutputStream(saveUri);
        if (outputStream != null) {
          croppedImage.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
        }
      } catch (IOException e) {
        setResultException(e);
        Log.e("Cannot open file: " + saveUri, e);
      } finally {
        CropUtil.closeSilently(outputStream);
      }

      CropUtil.copyExifRotation(
          CropUtil.getFromMediaUri(this, getContentResolver(), sourceUri),
          CropUtil.getFromMediaUri(this, getContentResolver(), saveUri));

      setResultUri(saveUri);
    }

    final Bitmap b = croppedImage;
    handler.post(
        new Runnable() {
          public void run() {
            imageView.clear();
            b.recycle();
          }
        });

    finish();
  }
  private void onSaveClicked() {
    if (cropView == null || isSaving) {
      return;
    }
    isSaving = true;

    Bitmap croppedImage;
    Rect r = cropView.getScaledCropRect(sampleSize);
    int width = r.width();
    int height = r.height();

    int outWidth = width;
    int outHeight = height;
    if (maxX > 0 && maxY > 0 && (width > maxX || height > maxY)) {
      float ratio = (float) width / (float) height;
      if ((float) maxX / (float) maxY > ratio) {
        outHeight = maxY;
        outWidth = (int) ((float) maxY * ratio + .5f);
      } else {
        outWidth = maxX;
        outHeight = (int) ((float) maxX / ratio + .5f);
      }
    }

    try {
      croppedImage = decodeRegionCrop(r, outWidth, outHeight);
    } catch (IllegalArgumentException e) {
      setResultException(e);
      finish();
      return;
    }

    if (croppedImage != null) {
      imageView.setImageRotateBitmapResetBase(new RotateBitmap(croppedImage, exifRotation), true);
      imageView.center();
      imageView.highlightViews.clear();
    }
    saveImage(croppedImage);
  }
  private Bitmap decodeRegionCrop(Rect rect, int outWidth, int outHeight) {
    // Release memory now
    clearImageView();

    InputStream is = null;
    Bitmap croppedImage = null;
    try {
      is = getContentResolver().openInputStream(sourceUri);
      BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
      final int width = decoder.getWidth();
      final int height = decoder.getHeight();

      if (exifRotation != 0) {
        // Adjust crop area to account for image rotation
        Matrix matrix = new Matrix();
        matrix.setRotate(-exifRotation);

        RectF adjusted = new RectF();
        matrix.mapRect(adjusted, new RectF(rect));

        // Adjust to account for origin at 0,0
        adjusted.offset(adjusted.left < 0 ? width : 0, adjusted.top < 0 ? height : 0);
        rect =
            new Rect(
                (int) adjusted.left,
                (int) adjusted.top,
                (int) adjusted.right,
                (int) adjusted.bottom);
      }

      try {
        croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options());

        /*     Part of code with BUG
                   if (croppedImage != null && (rect.width() >= outWidth || rect.height() >= outHeight)) {
                            Matrix matrix = new Matrix();
                            matrix.postScale((float) outWidth / rect.width(), (float) outHeight / rect.height());
                            croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), matrix, true);
        }*/
      } catch (IllegalArgumentException e) {
        // Rethrow with some extra information
        throw new IllegalArgumentException(
            "Rectangle "
                + rect
                + " is outside of the image ("
                + width
                + ","
                + height
                + ","
                + exifRotation
                + ")",
            e);
      }

    } catch (IOException e) {
      Log.e("Error cropping image: " + e.getMessage(), e);
      setResultException(e);
    } catch (OutOfMemoryError e) {
      Log.e("OOM cropping image: " + e.getMessage(), e);
      setResultException(e);
    } finally {
      CropUtil.closeSilently(is);
    }
    return croppedImage;
  }