private void SaveOutput(Bitmap croppedImage)
        {
            if (saveUri != null)
            {
                try
                {
                    using (var outputStream = ContentResolver.OpenOutputStream(saveUri))
                    {
                        if (outputStream != null)
                        {
                            croppedImage.Compress(outputFormat, 75, outputStream);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(this.GetType().Name, ex.Message);
                }

                Bundle extras = new Bundle();
                SetResult(Result.Ok, new Intent(saveUri.ToString())
                          .PutExtras(extras));
                CropImageServiceAndroid.SetResult(new CropResult(true)
                {
                    FilePath = saveUri.Path, Message = "Image cropped successfully"
                });
            }
            else
            {
                Log.Error(this.GetType().Name, "not defined image url");
            }
            croppedImage.Recycle();
            Finish();
        }
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            RequestWindowFeature(Android.Views.WindowFeatures.NoTitle);
            SetContentView(Resource.Layout.cropimage);

            imageView = FindViewById <CropImageView>(Resource.Id.image);

            showStorageToast(this);

            Bundle extras = Intent.Extras;

            if (extras != null)
            {
                imagePath = extras.GetString("image-path");

                saveUri = getImageUri(imagePath);
                if (extras.GetString(MediaStore.ExtraOutput) != null)
                {
                    saveUri = getImageUri(extras.GetString(MediaStore.ExtraOutput));
                }

                bitmap = getBitmap(imagePath);

                aspectX = extras.GetInt("aspectX");
                aspectY = extras.GetInt("aspectY");
                outputX = extras.GetInt("outputX");
                outputY = extras.GetInt("outputY");
                scale   = extras.GetBoolean("scale", true);
                scaleUp = extras.GetBoolean("scaleUpIfNeeded", true);

                if (extras.GetString("outputFormat") != null)
                {
                    outputFormat = Bitmap.CompressFormat.ValueOf(extras.GetString("outputFormat"));
                }
            }

            if (bitmap == null)
            {
                Finish();
                return;
            }

            Window.AddFlags(WindowManagerFlags.Fullscreen);


            FindViewById <Button>(Resource.Id.cancel).Click += (sender, e) =>
            {
                CropImageServiceAndroid.SetResult(new CropResult(false)
                {
                    Message = "Cancelled"
                });
                Finish();
                return;
            };
            FindViewById <Button>(Resource.Id.done).Click += (sender, e) => { OnSaveClicked(); };

            FindViewById <Button>(Resource.Id.rotateLeft).Click += (o, e) =>
            {
                bitmap = Util.rotateImage(bitmap, -90);
                RotateBitmap rotateBitmap = new RotateBitmap(bitmap);
                imageView.SetImageRotateBitmapResetBase(rotateBitmap, true);
                addHighlightView();
            };

            //FindViewById<Button>(Resource.Id.rotateRight).Click += (o, e) =>
            //{
            //    bitmap = Util.rotateImage(bitmap, 90);
            //    RotateBitmap rotateBitmap = new RotateBitmap(bitmap);
            //    imageView.SetImageRotateBitmapResetBase(rotateBitmap, true);
            //    addHighlightView();
            //};

            imageView.SetImageBitmapResetBase(bitmap, true);
            addHighlightView();
        }
        private void OnSaveClicked()
        {
            // TODO this code needs to change to use the decode/crop/encode single
            // step api so that we don't require that the whole (possibly large)
            // bitmap doesn't have to be read into memory
            if (Saving)
            {
                return;
            }

            Saving = true;

            var r = Crop.CropRect;

            int width  = r.Width();
            int height = r.Height();

            Bitmap croppedImage = Bitmap.CreateBitmap(width, height, Bitmap.Config.Rgb565);

            {
                Canvas canvas  = new Canvas(croppedImage);
                Rect   dstRect = new Rect(0, 0, width, height);
                canvas.DrawBitmap(bitmap, r, dstRect, null);
            }

            // If the output is required to a specific size then scale or fill
            if (outputX != 0 && outputY != 0)
            {
                if (scale)
                {
                    // Scale the image to the required dimensions
                    Bitmap old = croppedImage;
                    croppedImage = Util.transform(new Matrix(),
                                                  croppedImage, outputX, outputY, scaleUp);
                    if (old != croppedImage)
                    {
                        old.Recycle();
                    }
                }
                else
                {
                    // Don't scale the image crop it to the size requested.
                    // Create an new image with the cropped image in the center and
                    // the extra space filled.
                    Bitmap b = Bitmap.CreateBitmap(outputX, outputY,
                                                   Bitmap.Config.Rgb565);
                    Canvas canvas = new Canvas(b);

                    Rect srcRect = Crop.CropRect;
                    Rect dstRect = new Rect(0, 0, outputX, outputY);

                    int dx = (srcRect.Width() - dstRect.Width()) / 2;
                    int dy = (srcRect.Height() - dstRect.Height()) / 2;

                    // If the srcRect is too big, use the center part of it.
                    srcRect.Inset(Math.Max(0, dx), Math.Max(0, dy));

                    // If the dstRect is too big, use the center part of it.
                    dstRect.Inset(Math.Max(0, -dx), Math.Max(0, -dy));

                    // Draw the cropped bitmap in the center
                    canvas.DrawBitmap(bitmap, srcRect, dstRect, null);

                    // Set the cropped bitmap as the new bitmap
                    croppedImage.Recycle();
                    croppedImage = b;
                }
            }

            // Return the cropped image directly or save it to the specified URI.
            Bundle myExtras = Intent.Extras;

            if (myExtras != null &&
                (myExtras.GetParcelable("data") != null || myExtras.GetBoolean("return-data")))
            {
                Bundle extras = new Bundle();
                extras.PutParcelable("data", croppedImage);
                SetResult(Result.Ok, (new Intent()).SetAction("inline-data").PutExtras(extras));
                CropImageServiceAndroid.SetResult(new CropResult(true)
                {
                    FilePath = saveUri.Path, Message = "Image cropped successfully"
                });
                Finish();
            }
            else
            {
                Bitmap b = croppedImage;
                BackgroundJob.StartBackgroundJob(this, null, "Saving image", () => SaveOutput(b), mHandler);
            }
        }