content: package com.yalantis.ucrop;
  
  import android.annotation.TargetApi;
  import android.content.Intent;
  import android.graphics.Bitmap;
  import android.graphics.PorterDuff;
  import android.graphics.drawable.Drawable;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Bundle;
  import android.support.annotation.ColorInt;
  import android.support.annotation.IdRes;
  import android.support.annotation.IntDef;
  import android.support.annotation.NonNull;
  import android.support.v4.content.ContextCompat;
  import android.support.v7.app.ActionBar;
  import android.support.v7.app.AppCompatActivity;
  import android.support.v7.widget.Toolbar;
  import android.text.TextUtils;
  import android.util.Log;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.animation.Animation;
  import android.view.animation.AnimationUtils;
  import android.widget.ImageView;
  import android.widget.TextView;
  
  import com.yalantis.ucrop.util.BitmapLoadUtils;
  import com.yalantis.ucrop.util.SelectedStateListDrawable;
  import com.yalantis.ucrop.view.CropImageView;
  import com.yalantis.ucrop.view.GestureCropImageView;
  import com.yalantis.ucrop.view.OverlayView;
  import com.yalantis.ucrop.view.TransformImageView;
  import com.yalantis.ucrop.view.UCropView;
  import com.yalantis.ucrop.view.widget.AspectRatioTextView;
  import com.yalantis.ucrop.view.widget.HorizontalProgressWheelView;
  
  import java.io.OutputStream;
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Created by Oleksii Shliama (https://github.com/shliama).
   */
  public class UCropActivity extends AppCompatActivity {
  
      public static final int DEFAULT_COMPRESS_QUALITY = 90;
      public static final Bitmap.CompressFormat DEFAULT_COMPRESS_FORMAT = Bitmap.CompressFormat.JPEG;
  
      public static final int NONE = 0;
      public static final int SCALE = 1;
      public static final int ROTATE = 2;
      public static final int ALL = 3;
  
      @IntDef({NONE, SCALE, ROTATE, ALL})
      @Retention(RetentionPolicy.SOURCE)
      public @interface GestureTypes {
  
      }
  
      private static final String TAG = "UCropActivity";
  
      private static final int TABS_COUNT = 3;
      private static final int SCALE_WIDGET_SENSITIVITY_COEFFICIENT = 15000;
      private static final int ROTATE_WIDGET_SENSITIVITY_COEFFICIENT = 42;
  
      private String mToolbarTitle;
  
      // Enables dynamic coloring
      private int mToolbarColor;
      private int mStatusBarColor;
      private int mActiveWidgetColor;
      private int mToolbarTextColor;
      private int mLogoColor;
  
      private UCropView mUCropView;
      private GestureCropImageView mGestureCropImageView;
      private OverlayView mOverlayView;
      private ViewGroup mWrapperStateAspectRatio, mWrapperStateRotate, mWrapperStateScale;
      private ViewGroup mLayoutAspectRatio, mLayoutRotate, mLayoutScale;
      private List<ViewGroup> mCropAspectRatioViews = new ArrayList<>();
      private TextView mTextViewRotateAngle, mTextViewScalePercent;
  
      private Uri mOutputUri;
  
      private Bitmap.CompressFormat mCompressFormat = DEFAULT_COMPRESS_FORMAT;
      private int mCompressQuality = DEFAULT_COMPRESS_QUALITY;
      private int[] mAllowedGestures = new int[]{SCALE, ROTATE, ALL};
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.ucrop_activity_photobox);
  
          final Intent intent = getIntent();
  
          setupViews(intent);
          setImageData(intent);
          setInitialState();
      }
  
      @Override
      public boolean onCreateOptionsMenu(final Menu menu) {
          getMenuInflater().inflate(R.menu.ucrop_menu_activity, menu);
  
          // Change the next menu icon color to match the rest of the UI colors
          MenuItem next = menu.findItem(R.id.menu_crop);
  
          Drawable defaultIcon = next.getIcon();
          if (defaultIcon != null) {
              defaultIcon.mutate();
              defaultIcon.setColorFilter(mToolbarTextColor, PorterDuff.Mode.SRC_ATOP);
              next.setIcon(defaultIcon);
          }
  
          return true;
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          if (item.getItemId() == R.id.menu_crop) {
              cropAndSaveImage();
          } else if (item.getItemId() == android.R.id.home) {
              onBackPressed();
          }
          return super.onOptionsItemSelected(item);
      }
  
      @Override
      protected void onStop() {
          super.onStop();
          if (mGestureCropImageView != null) {
              mGestureCropImageView.cancelAllAnimations();
          }
      }
  
      /**
       * This method extracts all data from the incoming intent and setups views properly.
       */
      private void setImageData(@NonNull Intent intent) {
          Uri inputUri = intent.getParcelableExtra(UCrop.EXTRA_INPUT_URI);
          mOutputUri = intent.getParcelableExtra(UCrop.EXTRA_OUTPUT_URI);
          processOptions(intent);
  
          if (inputUri != null && mOutputUri != null) {
              try {
                  mGestureCropImageView.setImageUri(inputUri);
              } catch (Exception e) {
                  setResultException(e);
                  finish();
              }
          } else {
              setResultException(new NullPointerException(getString(R.string.ucrop_error_input_data_is_absent)));
              finish();
          }
  
          if (intent.getBooleanExtra(UCrop.EXTRA_ASPECT_RATIO_SET, false)) {
              mWrapperStateAspectRatio.setVisibility(View.GONE);
  
              float aspectRatioX = intent.getFloatExtra(UCrop.EXTRA_ASPECT_RATIO_X, 0);
              float aspectRatioY = intent.getFloatExtra(UCrop.EXTRA_ASPECT_RATIO_Y, 0);
  
              if (aspectRatioX > 0 && aspectRatioY > 0) {
                  mGestureCropImageView.setTargetAspectRatio(aspectRatioX / aspectRatioY);
              } else {
                  mGestureCropImageView.setTargetAspectRatio(CropImageView.SOURCE_IMAGE_ASPECT_RATIO);
              }
          }
  
          if (intent.getBooleanExtra(UCrop.EXTRA_MAX_SIZE_SET, false)) {
              int maxSizeX = intent.getIntExtra(UCrop.EXTRA_MAX_SIZE_X, 0);
              int maxSizeY = intent.getIntExtra(UCrop.EXTRA_MAX_SIZE_Y, 0);
  
              if (maxSizeX > 0 && maxSizeY > 0) {
                  mGestureCropImageView.setMaxResultImageSizeX(maxSizeX);
                  mGestureCropImageView.setMaxResultImageSizeY(maxSizeY);
              } else {
                  Log.w(TAG, "EXTRA_MAX_SIZE_X and EXTRA_MAX_SIZE_Y must be greater than 0");
              }
          }
      }
  
      /**
       * This method extracts {@link com.yalantis.ucrop.UCrop.Options #optionsBundle} from incoming intent
       * and setups Activity, {@link OverlayView} and {@link CropImageView} properly.
       */
      @SuppressWarnings("deprecation")
      private void processOptions(@NonNull Intent intent) {
          // Bitmap compression options
          String compressionFormatName = intent.getStringExtra(UCrop.Options.EXTRA_COMPRESSION_FORMAT_NAME);
          Bitmap.CompressFormat compressFormat = null;
          if (!TextUtils.isEmpty(compressionFormatName)) {
              compressFormat = Bitmap.CompressFormat.valueOf(compressionFormatName);
          }
          mCompressFormat = (compressFormat == null) ? DEFAULT_COMPRESS_FORMAT : compressFormat;
  
          mCompressQuality = intent.getIntExtra(UCrop.Options.EXTRA_COMPRESSION_QUALITY, UCropActivity.DEFAULT_COMPRESS_QUALITY);
  
          // Gestures options
          int[] allowedGestures = intent.getIntArrayExtra(UCrop.Options.EXTRA_ALLOWED_GESTURES);
          if (allowedGestures != null && allowedGestures.length == TABS_COUNT) {
              mAllowedGestures = allowedGestures;
          }
  
          // Crop image view options
          mGestureCropImageView.setMaxBitmapSize(intent.getIntExtra(UCrop.Options.EXTRA_MAX_BITMAP_SIZE, CropImageView.DEFAULT_MAX_BITMAP_SIZE));
          mGestureCropImageView.setMaxScaleMultiplier(intent.getFloatExtra(UCrop.Options.EXTRA_MAX_SCALE_MULTIPLIER, CropImageView.DEFAULT_MAX_SCALE_MULTIPLIER));
          mGestureCropImageView.setImageToWrapCropBoundsAnimDuration(intent.getIntExtra(UCrop.Options.EXTRA_IMAGE_TO_CROP_BOUNDS_ANIM_DURATION, CropImageView.DEFAULT_IMAGE_TO_CROP_BOUNDS_ANIM_DURATION));
  
  
          // Overlay view options
          mOverlayView.setDimmedColor(intent.getIntExtra(UCrop.Options.EXTRA_DIMMED_LAYER_COLOR, getResources().getColor(R.color.ucrop_color_default_dimmed)));
          mOverlayView.setOvalDimmedLayer(intent.getBooleanExtra(UCrop.Options.EXTRA_OVAL_DIMMED_LAYER, OverlayView.DEFAULT_OVAL_DIMMED_LAYER));
  
          mOverlayView.setShowCropFrame(intent.getBooleanExtra(UCrop.Options.EXTRA_SHOW_CROP_FRAME, OverlayView.DEFAULT_SHOW_CROP_FRAME));
          mOverlayView.setCropFrameColor(intent.getIntExtra(UCrop.Options.EXTRA_CROP_FRAME_COLOR, getResources().getColor(R.color.ucrop_color_default_crop_frame)));
          mOverlayView.setCropFrameStrokeWidth(intent.getIntExtra(UCrop.Options.EXTRA_CROP_FRAME_STROKE_WIDTH, getResources().getDimensionPixelSize(R.dimen.ucrop_default_crop_frame_stoke_width)));
  
          mOverlayView.setShowCropGrid(intent.getBooleanExtra(UCrop.Options.EXTRA_SHOW_CROP_GRID, OverlayView.DEFAULT_SHOW_CROP_GRID));
          mOverlayView.setCropGridRowCount(intent.getIntExtra(UCrop.Options.EXTRA_CROP_GRID_ROW_COUNT, OverlayView.DEFAULT_CROP_GRID_ROW_COUNT));
          mOverlayView.setCropGridColumnCount(intent.getIntExtra(UCrop.Options.EXTRA_CROP_GRID_COLUMN_COUNT, OverlayView.DEFAULT_CROP_GRID_COLUMN_COUNT));
          mOverlayView.setCropGridColor(intent.getIntExtra(UCrop.Options.EXTRA_CROP_GRID_COLOR, getResources().getColor(R.color.ucrop_color_default_crop_grid)));
          mOverlayView.setCropGridStrokeWidth(intent.getIntExtra(UCrop.Options.EXTRA_CROP_GRID_STROKE_WIDTH, getResources().getDimensionPixelSize(R.dimen.ucrop_default_crop_grid_stoke_width)));
      }
  
      private void setupViews(@NonNull Intent intent) {
          mStatusBarColor = intent.getIntExtra(UCrop.Options.EXTRA_STATUS_BAR_COLOR, ContextCompat.getColor(this, R.color.ucrop_color_statusbar));
          mToolbarColor = intent.getIntExtra(UCrop.Options.EXTRA_TOOL_BAR_COLOR, ContextCompat.getColor(this, R.color.ucrop_color_toolbar));
          mActiveWidgetColor = intent.getIntExtra(UCrop.Options.EXTRA_UCROP_COLOR_WIDGET_ACTIVE, ContextCompat.getColor(this, R.color.ucrop_color_widget_active));
          mToolbarTextColor = intent.getIntExtra(UCrop.Options.EXTRA_UCROP_TITLE_COLOR_TOOLBAR, ContextCompat.getColor(this, R.color.ucrop_color_title));
          mToolbarTitle = intent.getStringExtra(UCrop.Options.EXTRA_UCROP_TITLE_TEXT_TOOLBAR);
          mToolbarTitle = !TextUtils.isEmpty(mToolbarTitle) ? mToolbarTitle : getResources().getString(R.string.ucrop_label_edit_photo);
          mLogoColor = intent.getIntExtra(UCrop.Options.EXTRA_UCROP_LOGO_COLOR, ContextCompat.getColor(this, R.color.ucrop_color_default_logo));
  
          setupAppBar();
          initiateRootViews();
          setupAspectRatioWidget();
          setupRotateWidget();
          setupScaleWidget();
          setupStatesWrapper();
      }
  
      /**
       * Configures and styles both status bar and toolbar.
       */
      private void setupAppBar() {
          setStatusBarColor(mStatusBarColor);
  
          final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
  
          // Set all of the Toolbar coloring
          toolbar.setBackgroundColor(mToolbarColor);
          toolbar.setTitleTextColor(mToolbarTextColor);
  
          final TextView toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
          toolbarTitle.setTextColor(mToolbarTextColor);
          toolbarTitle.setText(mToolbarTitle);
  
          // Color buttons inside the Toolbar
          Drawable stateButtonDrawable = ContextCompat.getDrawable(this, R.drawable.ucrop_ic_cross).mutate();
          stateButtonDrawable.setColorFilter(mToolbarTextColor, PorterDuff.Mode.SRC_ATOP);
          toolbar.setNavigationIcon(stateButtonDrawable);
  
          setSupportActionBar(toolbar);
          final ActionBar actionBar = getSupportActionBar();
          if (actionBar != null) {
              actionBar.setDisplayShowTitleEnabled(false);
          }
      }
  
      private void initiateRootViews() {
          mUCropView = (UCropView) findViewById(R.id.ucrop);
          mGestureCropImageView = mUCropView.getCropImageView();
          mOverlayView = mUCropView.getOverlayView();
  
          mGestureCropImageView.setTransformImageListener(mImageListener);
  
          mWrapperStateAspectRatio = (ViewGroup) findViewById(R.id.state_aspect_ratio);
          mWrapperStateAspectRatio.setOnClickListener(mStateClickListener);
          mWrapperStateRotate = (ViewGroup) findViewById(R.id.state_rotate);
          mWrapperStateRotate.setOnClickListener(mStateClickListener);
          mWrapperStateScale = (ViewGroup) findViewById(R.id.state_scale);
          mWrapperStateScale.setOnClickListener(mStateClickListener);
  
          mLayoutAspectRatio = (ViewGroup) findViewById(R.id.layout_aspect_ratio);
          mLayoutRotate = (ViewGroup) findViewById(R.id.layout_rotate_wheel);
          mLayoutScale = (ViewGroup) findViewById(R.id.layout_scale_wheel);
  
          ((ImageView) findViewById(R.id.image_view_logo)).setColorFilter(mLogoColor, PorterDuff.Mode.SRC_ATOP);
      }
  
      private TransformImageView.TransformImageListener mImageListener = new TransformImageView.TransformImageListener() {
          @Override
          public void onRotate(float currentAngle) {
              setAngleText(currentAngle);
          }
  
          @Override
          public void onScale(float currentScale) {
              setScaleText(currentScale);
          }
  
          @Override
          public void onLoadComplete() {
              View ucropView = findViewById(R.id.ucrop);
              Animation fadeInAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.ucrop_fade_in);
              fadeInAnimation.setAnimationListener(new Animation.AnimationListener() {
                  @Override
                  public void onAnimationStart(Animation animation) {
                      mUCropView.setVisibility(View.VISIBLE);
                  }
  
                  @Override
                  public void onAnimationEnd(Animation animation) {
  
                  }
  
                  @Override
                  public void onAnimationRepeat(Animation animation) {
                  }
              });
              ucropView.startAnimation(fadeInAnimation);
          }
  
          @Override
          public void onLoadFailure(@NonNull Exception e) {
              setResultException(e);
              finish();
          }
  
      };
  
      /**
       * Use {@link #mActiveWidgetColor} for color filter
       */
      private void setupStatesWrapper() {
          ImageView stateScaleImageView = (ImageView) findViewById(R.id.image_view_state_scale);
          ImageView stateRotateImageView = (ImageView) findViewById(R.id.image_view_state_rotate);
          ImageView stateAspectRatioImageView = (ImageView) findViewById(R.id.image_view_state_aspect_ratio);
  
          stateScaleImageView.setImageDrawable(new SelectedStateListDrawable(stateScaleImageView.getDrawable(), mActiveWidgetColor));
          stateRotateImageView.setImageDrawable(new SelectedStateListDrawable(stateRotateImageView.getDrawable(), mActiveWidgetColor));
          stateAspectRatioImageView.setImageDrawable(new SelectedStateListDrawable(stateAspectRatioImageView.getDrawable(), mActiveWidgetColor));
      }
  
  
      /**
       * Sets status-bar color for L devices.
       *
       * @param color - status-bar color
       */
      @TargetApi(Build.VERSION_CODES.LOLLIPOP)
      private void setStatusBarColor(@ColorInt int color) {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
              if (getWindow() != null) {
                  getWindow().setStatusBarColor(color);
              }
          }
      }
  
      private void setupAspectRatioWidget() {
  
          // Set the colors before the default item is selected
          ((AspectRatioTextView) ((ViewGroup) findViewById(R.id.crop_aspect_ratio_1_1)).getChildAt(0)).setActiveColor(mActiveWidgetColor);
          ((AspectRatioTextView) ((ViewGroup) findViewById(R.id.crop_aspect_ratio_3_4)).getChildAt(0)).setActiveColor(mActiveWidgetColor);
          ((AspectRatioTextView) ((ViewGroup) findViewById(R.id.crop_aspect_ratio_original)).getChildAt(0)).setActiveColor(mActiveWidgetColor);
          ((AspectRatioTextView) ((ViewGroup) findViewById(R.id.crop_aspect_ratio_3_2)).getChildAt(0)).setActiveColor(mActiveWidgetColor);
          ((AspectRatioTextView) ((ViewGroup) findViewById(R.id.crop_aspect_ratio_16_9)).getChildAt(0)).setActiveColor(mActiveWidgetColor);
  
          mCropAspectRatioViews.add((ViewGroup) findViewById(R.id.crop_aspect_ratio_1_1));
          mCropAspectRatioViews.add((ViewGroup) findViewById(R.id.crop_aspect_ratio_3_4));
          mCropAspectRatioViews.add((ViewGroup) findViewById(R.id.crop_aspect_ratio_original));
          mCropAspectRatioViews.add((ViewGroup) findViewById(R.id.crop_aspect_ratio_3_2));
          mCropAspectRatioViews.add((ViewGroup) findViewById(R.id.crop_aspect_ratio_16_9));
          mCropAspectRatioViews.get(2).setSelected(true);
  
          for (ViewGroup cropAspectRatioView : mCropAspectRatioViews) {
              cropAspectRatioView.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      mGestureCropImageView.setTargetAspectRatio(
                              ((AspectRatioTextView) ((ViewGroup) v).getChildAt(0)).getAspectRatio(v.isSelected()));
                      mGestureCropImageView.setImageToWrapCropBounds();
                      if (!v.isSelected()) {
                          for (ViewGroup cropAspectRatioView : mCropAspectRatioViews) {
                              cropAspectRatioView.setSelected(cropAspectRatioView == v);
                          }
                      }
                  }
              });
          }
      }
  
      private void setupRotateWidget() {
          mTextViewRotateAngle = ((TextView) findViewById(R.id.text_view_rotate));
          ((HorizontalProgressWheelView) findViewById(R.id.rotate_scroll_wheel))
                  .setScrollingListener(new HorizontalProgressWheelView.ScrollingListener() {
                      @Override
                      public void onScroll(float delta, float totalDistance) {
                          mGestureCropImageView.postRotate(delta / ROTATE_WIDGET_SENSITIVITY_COEFFICIENT);
                      }
  
                      @Override
                      public void onScrollEnd() {
                          mGestureCropImageView.setImageToWrapCropBounds();
                      }
  
                      @Override
                      public void onScrollStart() {
                          mGestureCropImageView.cancelAllAnimations();
                      }
                  });
  
          ((HorizontalProgressWheelView) findViewById(R.id.rotate_scroll_wheel)).setMiddleLineColor(mActiveWidgetColor);
  
  
          findViewById(R.id.wrapper_reset_rotate).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  resetRotation();
              }
          });
          findViewById(R.id.wrapper_rotate_by_angle).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  rotateByAngle(90);
              }
          });
      }
  
      private void setupScaleWidget() {
          mTextViewScalePercent = ((TextView) findViewById(R.id.text_view_scale));
          ((HorizontalProgressWheelView) findViewById(R.id.scale_scroll_wheel))
                  .setScrollingListener(new HorizontalProgressWheelView.ScrollingListener() {
                      @Override
                      public void onScroll(float delta, float totalDistance) {
                          if (delta > 0) {
                              mGestureCropImageView.zoomInImage(mGestureCropImageView.getCurrentScale()
                                      + delta * ((mGestureCropImageView.getMaxScale() - mGestureCropImageView.getMinScale()) / SCALE_WIDGET_SENSITIVITY_COEFFICIENT));
                          } else {
                              mGestureCropImageView.zoomOutImage(mGestureCropImageView.getCurrentScale()
                                      + delta * ((mGestureCropImageView.getMaxScale() - mGestureCropImageView.getMinScale()) / SCALE_WIDGET_SENSITIVITY_COEFFICIENT));
                          }
                      }
  
                      @Override
                      public void onScrollEnd() {
                          mGestureCropImageView.setImageToWrapCropBounds();
                      }
  
                      @Override
                      public void onScrollStart() {
                          mGestureCropImageView.cancelAllAnimations();
                      }
                  });
          ((HorizontalProgressWheelView) findViewById(R.id.scale_scroll_wheel)).setMiddleLineColor(mActiveWidgetColor);
      }
  
      private void setAngleText(float angle) {
          if (mTextViewRotateAngle != null) {
              mTextViewRotateAngle.setText(String.format("%.1f°", angle));
          }
      }
  
      private void setScaleText(float scale) {
          if (mTextViewScalePercent != null) {
              mTextViewScalePercent.setText(String.format("%d%%", (int) (scale * 100)));
          }
      }
  
      private void resetRotation() {
          mGestureCropImageView.postRotate(-mGestureCropImageView.getCurrentAngle());
          mGestureCropImageView.setImageToWrapCropBounds();
      }
  
      private void rotateByAngle(int angle) {
          mGestureCropImageView.postRotate(angle);
          mGestureCropImageView.setImageToWrapCropBounds();
      }
  
      private final View.OnClickListener mStateClickListener = new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              if (!v.isSelected()) {
                  setWidgetState(v.getId());
              }
          }
      };
  
      private void setInitialState() {
          if (mWrapperStateAspectRatio.getVisibility() == View.VISIBLE) {
              setWidgetState(R.id.state_aspect_ratio);
          } else {
              setWidgetState(R.id.state_scale);
          }
      }
  
      private void setWidgetState(@IdRes int stateViewId) {
          mWrapperStateAspectRatio.setSelected(stateViewId == R.id.state_aspect_ratio);
          mWrapperStateRotate.setSelected(stateViewId == R.id.state_rotate);
          mWrapperStateScale.setSelected(stateViewId == R.id.state_scale);
  
          mLayoutAspectRatio.setVisibility(stateViewId == R.id.state_aspect_ratio ? View.VISIBLE : View.GONE);
          mLayoutRotate.setVisibility(stateViewId == R.id.state_rotate ? View.VISIBLE : View.GONE);
          mLayoutScale.setVisibility(stateViewId == R.id.state_scale ? View.VISIBLE : View.GONE);
  
          if (stateViewId == R.id.state_scale) {
              setAllowedGestures(0);
          } else if (stateViewId == R.id.state_rotate) {
              setAllowedGestures(1);
          } else {
              setAllowedGestures(2);
          }
      }
  
      private void setAllowedGestures(int tab) {
          mGestureCropImageView.setScaleEnabled(mAllowedGestures[tab] == ALL || mAllowedGestures[tab] == SCALE);
          mGestureCropImageView.setRotateEnabled(mAllowedGestures[tab] == ALL || mAllowedGestures[tab] == ROTATE);
      }
  
      private void cropAndSaveImage() {
          OutputStream outputStream = null;
          try {
              final Bitmap croppedBitmap = mGestureCropImageView.cropImage();
              if (croppedBitmap != null) {
                  outputStream = getContentResolver().openOutputStream(mOutputUri);
                  croppedBitmap.compress(mCompressFormat, mCompressQuality, outputStream);
                  croppedBitmap.recycle();
  
                  setResultUri(mOutputUri, mGestureCropImageView.getTargetAspectRatio());
                  finish();
              } else {
                  setResultException(new NullPointerException("CropImageView.cropImage() returned null."));
              }
          } catch (Exception e) {
              setResultException(e);
              finish();
          } finally {
              BitmapLoadUtils.close(outputStream);
          }
      }
  
      private void setResultUri(Uri uri, float resultAspectRatio) {
          setResult(RESULT_OK, new Intent()
                  .putExtra(UCrop.EXTRA_OUTPUT_URI, uri)
                  .putExtra(UCrop.EXTRA_OUTPUT_CROP_ASPECT_RATIO, resultAspectRatio));
      }
  
      private void setResultException(Throwable throwable) {
          setResult(UCrop.RESULT_ERROR, new Intent().putExtra(UCrop.EXTRA_ERROR, throwable));
      }
  
  }
  