content: package com.yalantis.ucrop;
  
  import android.annotation.TargetApi;
  import android.app.Activity;
  import android.app.Fragment;
  import android.content.Context;
  import android.content.Intent;
  import android.graphics.Bitmap;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Bundle;
  import android.support.annotation.ColorInt;
  import android.support.annotation.FloatRange;
  import android.support.annotation.IntRange;
  import android.support.annotation.NonNull;
  import android.support.annotation.Nullable;
  
  /**
   * Created by Oleksii Shliama (https://github.com/shliama).
   * <p/>
   * Builder class to ease Intent setup.
   */
  public class UCrop {
  
      public static final int REQUEST_CROP = 69;
      public static final int RESULT_ERROR = 96;
  
      private static final String EXTRA_PREFIX = BuildConfig.APPLICATION_ID;
  
      public static final String EXTRA_INPUT_URI = EXTRA_PREFIX + ".InputUri";
      public static final String EXTRA_OUTPUT_URI = EXTRA_PREFIX + ".OutputUri";
      public static final String EXTRA_OUTPUT_CROP_ASPECT_RATIO = EXTRA_PREFIX + ".CropAspectRatio";
      public static final String EXTRA_ERROR = EXTRA_PREFIX + ".Error";
  
      public static final String EXTRA_ASPECT_RATIO_SET = EXTRA_PREFIX + ".AspectRatioSet";
      public static final String EXTRA_ASPECT_RATIO_X = EXTRA_PREFIX + ".AspectRatioX";
      public static final String EXTRA_ASPECT_RATIO_Y = EXTRA_PREFIX + ".AspectRatioY";
  
      public static final String EXTRA_MAX_SIZE_SET = EXTRA_PREFIX + ".MaxSizeSet";
      public static final String EXTRA_MAX_SIZE_X = EXTRA_PREFIX + ".MaxSizeX";
      public static final String EXTRA_MAX_SIZE_Y = EXTRA_PREFIX + ".MaxSizeY";
  
      private Intent mCropIntent;
      private Bundle mCropOptionsBundle;
  
      /**
       * This method creates new Intent builder and sets both source and destination image URIs.
       *
       * @param source      Uri for image to crop
       * @param destination Uri for saving the cropped image
       */
      public static UCrop of(@NonNull Uri source, @NonNull Uri destination) {
          return new UCrop(source, destination);
      }
  
      private UCrop(@NonNull Uri source, @NonNull Uri destination) {
          mCropIntent = new Intent();
          mCropOptionsBundle = new Bundle();
          mCropOptionsBundle.putParcelable(EXTRA_INPUT_URI, source);
          mCropOptionsBundle.putParcelable(EXTRA_OUTPUT_URI, destination);
      }
  
      /**
       * Set an aspect ratio for crop bounds.
       * User won't see the menu with other ratios options.
       *
       * @param x aspect ratio X
       * @param y aspect ratio Y
       */
      public UCrop withAspectRatio(float x, float y) {
          mCropOptionsBundle.putBoolean(EXTRA_ASPECT_RATIO_SET, true);
          mCropOptionsBundle.putFloat(EXTRA_ASPECT_RATIO_X, x);
          mCropOptionsBundle.putFloat(EXTRA_ASPECT_RATIO_Y, y);
          return this;
      }
  
      /**
       * Set an aspect ratio for crop bounds that is evaluated from source image width and height.
       * User won't see the menu with other ratios options.
       */
      public UCrop useSourceImageAspectRatio() {
          mCropOptionsBundle.putBoolean(EXTRA_ASPECT_RATIO_SET, true);
          mCropOptionsBundle.putInt(EXTRA_ASPECT_RATIO_X, 0);
          mCropOptionsBundle.putInt(EXTRA_ASPECT_RATIO_Y, 0);
          return this;
      }
  
      /**
       * Set maximum size for result cropped image.
       *
       * @param width  max cropped image width
       * @param height max cropped image height
       */
      public UCrop withMaxResultSize(@IntRange(from = 100) int width, @IntRange(from = 100) int height) {
          mCropOptionsBundle.putBoolean(EXTRA_MAX_SIZE_SET, true);
          mCropOptionsBundle.putInt(EXTRA_MAX_SIZE_X, width);
          mCropOptionsBundle.putInt(EXTRA_MAX_SIZE_Y, height);
          return this;
      }
  
      public UCrop withOptions(@NonNull Options options) {
          mCropOptionsBundle.putAll(options.getOptionBundle());
          return this;
      }
  
      /**
       * Send the crop Intent from an Activity
       *
       * @param activity Activity to receive result
       */
      public void start(@NonNull Activity activity) {
          start(activity, REQUEST_CROP);
      }
  
      /**
       * Send the crop Intent from an Activity with a custom request code
       *
       * @param activity    Activity to receive result
       * @param requestCode requestCode for result
       */
      public void start(@NonNull Activity activity, int requestCode) {
          activity.startActivityForResult(getIntent(activity), requestCode);
      }
  
      /**
       * Send the crop Intent from a Fragment
       *
       * @param fragment Fragment to receive result
       */
      public void start(@NonNull Context context, @NonNull Fragment fragment) {
          start(context, fragment, REQUEST_CROP);
      }
  
      /**
       * Send the crop Intent from a support library Fragment
       *
       * @param fragment Fragment to receive result
       */
      public void start(@NonNull Context context, @NonNull android.support.v4.app.Fragment fragment) {
          start(context, fragment, REQUEST_CROP);
      }
  
      /**
       * Send the crop Intent with a custom request code
       *
       * @param fragment    Fragment to receive result
       * @param requestCode requestCode for result
       */
      @TargetApi(Build.VERSION_CODES.HONEYCOMB)
      public void start(@NonNull Context context, @NonNull Fragment fragment, int requestCode) {
          fragment.startActivityForResult(getIntent(context), requestCode);
      }
  
      /**
       * Send the crop Intent with a custom request code
       *
       * @param fragment    Fragment to receive result
       * @param requestCode requestCode for result
       */
      public void start(@NonNull Context context, @NonNull android.support.v4.app.Fragment fragment, int requestCode) {
          fragment.startActivityForResult(getIntent(context), requestCode);
      }
  
      /**
       * Get Intent to start {@link UCropActivity}
       *
       * @return Intent for {@link UCropActivity}
       */
      public Intent getIntent(@NonNull Context context) {
          mCropIntent.setClass(context, UCropActivity.class);
          mCropIntent.putExtras(mCropOptionsBundle);
          return mCropIntent;
      }
  
      /**
       * Retrieve cropped image Uri from the result Intent
       *
       * @param intent crop result intent
       */
      @Nullable
      public static Uri getOutput(@NonNull Intent intent) {
          return intent.getParcelableExtra(EXTRA_OUTPUT_URI);
      }
  
      /**
       * Retrieve cropped image aspect ratio from the result Intent
       *
       * @param intent crop result intent
       * @return aspect ratio as a floating point value (x:y) - so it will be 1 for 1:1 or 4/3 for 4:3
       */
      public static float getOutputCropAspectRatio(@NonNull Intent intent) {
          return intent.getParcelableExtra(EXTRA_OUTPUT_CROP_ASPECT_RATIO);
      }
  
      /**
       * Method retrieves error from the result intent.
       *
       * @param result crop result Intent
       * @return Throwable that could happen while image processing
       */
      @Nullable
      public static Throwable getError(@NonNull Intent result) {
          return (Throwable) result.getSerializableExtra(EXTRA_ERROR);
      }
  
  
      /**
       * Class that helps to setup advanced configs that are not commonly used.
       * Use it with method {@link #withOptions(Options)}
       */
      public static class Options {
  
          public static final String EXTRA_COMPRESSION_FORMAT_NAME = EXTRA_PREFIX + ".CompressionFormatName";
          public static final String EXTRA_COMPRESSION_QUALITY = EXTRA_PREFIX + ".CompressionQuality";
  
          public static final String EXTRA_ALLOWED_GESTURES = EXTRA_PREFIX + ".AllowedGestures";
  
          public static final String EXTRA_MAX_BITMAP_SIZE = EXTRA_PREFIX + ".MaxBitmapSize";
          public static final String EXTRA_MAX_SCALE_MULTIPLIER = EXTRA_PREFIX + ".MaxScaleMultiplier";
          public static final String EXTRA_IMAGE_TO_CROP_BOUNDS_ANIM_DURATION = EXTRA_PREFIX + ".ImageToCropBoundsAnimDuration";
  
          public static final String EXTRA_DIMMED_LAYER_COLOR = EXTRA_PREFIX + ".DimmedLayerColor";
          public static final String EXTRA_OVAL_DIMMED_LAYER = EXTRA_PREFIX + ".OvalDimmedLayer";
  
          public static final String EXTRA_SHOW_CROP_FRAME = EXTRA_PREFIX + ".ShowCropFrame";
          public static final String EXTRA_CROP_FRAME_COLOR = EXTRA_PREFIX + ".CropFrameColor";
          public static final String EXTRA_CROP_FRAME_STROKE_WIDTH = EXTRA_PREFIX + ".CropFrameStrokeWidth";
  
          public static final String EXTRA_SHOW_CROP_GRID = EXTRA_PREFIX + ".ShowCropGrid";
          public static final String EXTRA_CROP_GRID_ROW_COUNT = EXTRA_PREFIX + ".CropGridRowCount";
          public static final String EXTRA_CROP_GRID_COLUMN_COUNT = EXTRA_PREFIX + ".CropGridColumnCount";
          public static final String EXTRA_CROP_GRID_COLOR = EXTRA_PREFIX + ".CropGridColor";
          public static final String EXTRA_CROP_GRID_STROKE_WIDTH = EXTRA_PREFIX + ".CropGridStrokeWidth";
  
          public static final String EXTRA_TOOL_BAR_COLOR = EXTRA_PREFIX + ".ToolbarColor";
          public static final String EXTRA_STATUS_BAR_COLOR = EXTRA_PREFIX + ".StatusBarColor";
          public static final String EXTRA_UCROP_COLOR_WIDGET_ACTIVE = EXTRA_PREFIX + ".UcropColorWidgetActive";
  
          public static final String EXTRA_UCROP_TITLE_COLOR_TOOLBAR = EXTRA_PREFIX + ".UcropToolbarTitleColor";
          public static final String EXTRA_UCROP_TITLE_TEXT_TOOLBAR = EXTRA_PREFIX + ".UcropToolbarTitleText";
  
          public static final String EXTRA_UCROP_LOGO_COLOR = EXTRA_PREFIX + ".UcropLogoColor";
  
  
          private final Bundle mOptionBundle;
  
          public Options() {
              mOptionBundle = new Bundle();
          }
  
          @NonNull
          public Bundle getOptionBundle() {
              return mOptionBundle;
          }
  
          /**
           * Set one of {@link android.graphics.Bitmap.CompressFormat} that will be used to save resulting Bitmap.
           */
          public void setCompressionFormat(@NonNull Bitmap.CompressFormat format) {
              mOptionBundle.putString(EXTRA_COMPRESSION_FORMAT_NAME, format.name());
          }
  
          /**
           * Set compression quality [0-100] that will be used to save resulting Bitmap.
           */
          public void setCompressionQuality(@IntRange(from = 0) int compressQuality) {
              mOptionBundle.putInt(EXTRA_COMPRESSION_QUALITY, compressQuality);
          }
  
          /**
           * Choose what set of gestures will be enabled on each tab - if any.
           */
          public void setAllowedGestures(@UCropActivity.GestureTypes int tabScale,
                                         @UCropActivity.GestureTypes int tabRotate,
                                         @UCropActivity.GestureTypes int tabAspectRatio) {
              mOptionBundle.putIntArray(EXTRA_ALLOWED_GESTURES, new int[]{tabScale, tabRotate, tabAspectRatio});
          }
  
          /**
           * This method sets multiplier that is used to calculate max image scale from min image scale.
           *
           * @param maxScaleMultiplier - (minScale * maxScaleMultiplier) = maxScale
           */
          public void setMaxScaleMultiplier(@FloatRange(from = 1.0, fromInclusive = false) float maxScaleMultiplier) {
              mOptionBundle.putFloat(EXTRA_MAX_SCALE_MULTIPLIER, maxScaleMultiplier);
          }
  
          /**
           * This method sets animation duration for image to wrap the crop bounds
           *
           * @param durationMillis - duration in milliseconds
           */
          public void setImageToCropBoundsAnimDuration(@IntRange(from = 100) int durationMillis) {
              mOptionBundle.putInt(EXTRA_IMAGE_TO_CROP_BOUNDS_ANIM_DURATION, durationMillis);
          }
  
          /**
           * Setter for max size for both width and height of bitmap that will be decoded from an input Uri and used in the view.
           *
           * @param maxBitmapSize - size in pixels
           */
          public void setMaxBitmapSize(@IntRange(from = 100) int maxBitmapSize) {
              mOptionBundle.putInt(EXTRA_MAX_BITMAP_SIZE, maxBitmapSize);
          }
  
          /**
           * @param color - desired color of dimmed area around the crop bounds
           */
          public void setDimmedLayerColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_DIMMED_LAYER_COLOR, color);
          }
  
          /**
           * @param isOval - set it to true if you want dimmed layer to have an oval inside
           */
          public void setOvalDimmedLayer(boolean isOval) {
              mOptionBundle.putBoolean(EXTRA_OVAL_DIMMED_LAYER, isOval);
          }
  
          /**
           * @param show - set to true if you want to see a crop frame rectangle on top of an image
           */
          public void setShowCropFrame(boolean show) {
              mOptionBundle.putBoolean(EXTRA_SHOW_CROP_FRAME, show);
          }
  
          /**
           * @param color - desired color of crop frame
           */
          public void setCropFrameColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_CROP_FRAME_COLOR, color);
          }
  
          /**
           * @param width - desired width of crop frame line in pixels
           */
          public void setCropFrameStrokeWidth(@IntRange(from = 0) int width) {
              mOptionBundle.putInt(EXTRA_CROP_FRAME_STROKE_WIDTH, width);
          }
  
          /**
           * @param show - set to true if you want to see a crop grid/guidelines on top of an image
           */
          public void setShowCropGrid(boolean show) {
              mOptionBundle.putBoolean(EXTRA_SHOW_CROP_GRID, show);
          }
  
          /**
           * @param count - crop grid rows count.
           */
          public void setCropGridRowCount(@IntRange(from = 0) int count) {
              mOptionBundle.putInt(EXTRA_CROP_GRID_ROW_COUNT, count);
          }
  
          /**
           * @param count - crop grid columns count.
           */
          public void setCropGridColumnCount(@IntRange(from = 0) int count) {
              mOptionBundle.putInt(EXTRA_CROP_GRID_COLUMN_COUNT, count);
          }
  
          /**
           * @param color - desired color of crop grid/guidelines
           */
          public void setCropGridColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_CROP_GRID_COLOR, color);
          }
  
          /**
           * @param width - desired width of crop grid lines in pixels
           */
          public void setCropGridStrokeWidth(@IntRange(from = 0) int width) {
              mOptionBundle.putInt(EXTRA_CROP_GRID_STROKE_WIDTH, width);
          }
  
          /**
           * @param color - desired resolved color of the toolbar
           */
          public void setToolbarColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_TOOL_BAR_COLOR, color);
          }
  
          /**
           * @param color - desired resolved color of the statusbar
           */
          public void setStatusBarColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_STATUS_BAR_COLOR, color);
          }
  
          /**
           * @param color - desired resolved color of the active and selected widget (default is orange) and progress wheel middle line
           */
          public void setActiveWidgetColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_UCROP_COLOR_WIDGET_ACTIVE, color);
          }
  
          /**
           * @param color - desired resolved color of Toolbar text and buttons (default is darker orange)
           */
          public void setToolbarTitleTextColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_UCROP_TITLE_COLOR_TOOLBAR, color);
          }
  
          /**
           * @param text - desired text for Toolbar title
           */
          public void setToolbarTitle(@Nullable String text) {
              mOptionBundle.putString(EXTRA_UCROP_TITLE_TEXT_TOOLBAR, text);
          }
  
          /**
           * @param color - desired resolved color of logo fill (default is darker grey)
           */
          public void setLogoColor(@ColorInt int color) {
              mOptionBundle.putInt(EXTRA_UCROP_LOGO_COLOR, color);
          }
  
      }
  
  }