Ejemplo n.º 1
0
        private void AddImageAction(string fakeImagePath, int cropSize, bool isMakePhoto)
        {
            Task <MediaFile> imageTask = null;
            var options = new CameraMediaStorageOptions
            {
                DefaultCamera     = CameraDevice.Rear,
                MaxPixelDimension = 400,
            };

            if (isMakePhoto && AppProvider.MediaPicker.IsCameraAvailable)
            {
                imageTask = AppProvider.MediaPicker.TakePhotoAsync(options);
            }
            else
            {
                imageTask = AppProvider.MediaPicker.SelectPhotoAsync(options);
            }

            imageTask.ContinueWith(delegate(Task <MediaFile> arg) {
                MediaFile file = arg.Result;

                if (file != null)
                {
                    AppProvider.IOManager.DeleteFile(fakeImagePath);
                    AppProvider.ImageService.CropAndResizeImage(file.Path, fakeImagePath, cropSize);
                    OnImageChanged();

                    //onExecuted.Invoke();
                }
            });
        }
        /// <summary>
        /// Creates the media intent.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <param name="type">The type of intent.</param>
        /// <param name="action">The action.</param>
        /// <param name="options">The options.</param>
        /// <param name="tasked">if set to <c>true</c> [tasked].</param>
        /// <returns>Intent to create media.</returns>
        private Intent CreateMediaIntent(
            int id,
            string type,
            string action,
            CameraMediaStorageOptions options,
            bool tasked = true)
        {
            // Create the intent
            var pickerIntent = new Intent(MediaPickerDroid.Context, typeof(MediaPickerActivity));

            pickerIntent.SetFlags(ActivityFlags.NewTask);
            pickerIntent.PutExtra(MediaPickerActivity.ExtraId, id);
            pickerIntent.PutExtra(MediaPickerActivity.ExtraType, type);
            pickerIntent.PutExtra(MediaPickerActivity.ExtraAction, action);
            pickerIntent.PutExtra(MediaPickerActivity.ExtraTasked, tasked);

            // Set the additional options
            if (options != null)
            {
                pickerIntent.PutExtra(MediaPickerActivity.ExtraPath, options.Directory);
                pickerIntent.PutExtra(MediaStore.Images.ImageColumns.Title, options.Name);
            }

            // Remove the created intent
            return(pickerIntent);
        }
        /// <summary>
        /// Takes the photo from the device camera.
        /// </summary>
        private void TakePhoto()
        {
            // If the camera available
            var picker = MediaPicker.Instance;

            if ((picker != null) && picker.IsCameraAvailable)
            {
                // Take the photo
                var options   = new CameraMediaStorageOptions();
                var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
                var task      = picker.TakePhotoAsync(options);
                if (task != null)
                {
                    // Process taken photo
                    task.ContinueWith(this.OnPhotoChoosen, scheduler);
                }
                else
                {
                    App.DisplayAlert(
                        Localization.ErrorDialogTitle,
                        Localization.ErrorCameraForbidden,
                        Localization.DialogDismiss);
                }
            }
            else
            {
                App.DisplayAlert(
                    Localization.ErrorDialogTitle,
                    Localization.ErrorCameraUnavailable,
                    Localization.DialogDismiss);
            }
        }
        /// <summary>
        /// Takes the picture.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task representing the asynchronous operation.</returns>
        public override Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            // Create a new instance of the file picker
            var filePicker = new FileOpenPicker
            {
                SuggestedStartLocation = PickerLocationId.PicturesLibrary,
                ViewMode = PickerViewMode.Thumbnail
            };

            // Filter to include a sample subset of file types
            filePicker.FileTypeFilter.Clear();
            filePicker.FileTypeFilter.Add(".bmp");
            filePicker.FileTypeFilter.Add(".png");
            filePicker.FileTypeFilter.Add(".jpeg");
            filePicker.FileTypeFilter.Add(".jpg");

            // If the choose photo operation is in progress
            var source = new TaskCompletionSource <MediaFile>();

            if (Interlocked.CompareExchange(ref this.completionSource, source, null) != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            // Choose the photo
            this.view = CoreApplication.GetCurrentView();
            filePicker.PickSingleFileAndContinue();
            this.view.Activated += this.OnViewActivated;
            return(this.completionSource.Task);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Setups the controller.
        /// </summary>
        /// <param name="mediaDelegate">The media picker delegate.</param>
        /// <param name="sourceType">Media source type.</param>
        /// <param name="mediaType">Media type.</param>
        /// <param name="options">The options.</param>
        /// <returns>The configured media picker controller.</returns>
        private static MediaPickerController SetupController(
            MediaPickerDelegate mediaDelegate,
            UIImagePickerControllerSourceType sourceType,
            string mediaType,
            CameraMediaStorageOptions options = null)
        {
            // Create the media picker
            var picker = new MediaPickerController(mediaDelegate)
            {
                MediaTypes = new[] { mediaType },
                SourceType = sourceType
            };

            // If the image is from camera
            if (sourceType == UIImagePickerControllerSourceType.Camera)
            {
                if ((mediaType == MediaPickerIOS.TypeImage) && (options != null))
                {
                    // Configure the camera
                    picker.CameraDevice      = MediaPickerIOS.GetCameraDevice(options.DefaultCamera);
                    picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Photo;
                }
            }

            return(picker);
        }
Ejemplo n.º 6
0
        private async Task TakeImage()
        {
            var cameraOpts = new CameraMediaStorageOptions();

            cameraOpts.PercentQuality    = 50;
            cameraOpts.MaxPixelDimension = 1200;

            var result = await UIUtils.ShowSelectList("Take a photo", "Choose from library", this);

            System.Threading.Tasks.Task <MediaFile> taskMedia = null;
            if (result == 1)
            {
                taskMedia = DependencyService.Get <IMediaPicker>().TakePhotoAsync(cameraOpts);
            }
            else if (result == 2)
            {
                taskMedia = DependencyService.Get <IMediaPicker>().SelectPhotoAsync(cameraOpts);
            }
            else
            {
                return;
            }
            await taskMedia.ContinueWith((t, o) =>
            {
                if (t.IsCanceled || t.Result == null)
                {
                    return;
                }
                photoFile = t.Result;
            }, null);
        }
 /// <summary>
 /// Verifies the camera options.
 /// </summary>
 /// <param name="options">The options.</param>
 /// <exception cref="ArgumentException">options.Camera is not a member of CameraDevice</exception>
 private static void VerifyCameraOptions(CameraMediaStorageOptions options)
 {
     VerifyOptions(options);
     if (!Enum.IsDefined(typeof(CameraDevice), options.DefaultCamera))
     {
         throw new ArgumentException("options.Camera is not a member of CameraDevice");
     }
 }
        /// <summary>
        /// Select a picture from library.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task&lt;IMediaFile&gt;.</returns>
        /// <exception cref="NotSupportedException"></exception>
        public Task <MediaFile> SelectPhotoAsync(CameraMediaStorageOptions options)
        {
            if (!IsPhotosSupported)
            {
                throw new NotSupportedException();
            }

            return(GetMediaAsync(UIImagePickerControllerSourceType.PhotoLibrary, TypeImage));
        }
        private async Task <MediaFile> TakePic()
        {
            var mediaStorageOptions = new CameraMediaStorageOptions
            {
                DefaultCamera = CameraDevice.Rear
            };
            var mediaFile = await _device.MediaPicker.TakePhotoAsync(mediaStorageOptions);

            return(mediaFile);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Select a picture from library.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task with a return type of MediaFile.</returns>
        /// <exception cref="System.NotSupportedException">Throws an exception if feature is not supported.</exception>
        public Task <MediaFile> SelectPhotoAsync(CameraMediaStorageOptions options)
        {
            if (!IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            options.VerifyOptions();

            return(TakeMediaAsync("image/*", Intent.ActionPick, options));
        }
Ejemplo n.º 11
0
        // ...
        //private byte[] ConvertYuvToJpeg(byte[] yuvData, CameraDevice camera)
        //{
        //    var cameraParameters = camera.;
        //    var width = cameraParameters.PreviewSize.Width;
        //    var height = cameraParameters.PreviewSize.Height;
        //    var yuv = new YuvImage(yuvData, cameraParameters.PreviewFormat, width, height, null);
        //    var ms = new MemoryStream();
        //    var quality = 80;   // adjust this as needed
        //    yuv.CompressToJpeg(new Rect(0, 0, width, height), quality, ms);
        //    var jpegData = ms.ToArray();

        //    return jpegData;
        //}
        private async Task <MediaFile> TakePic()
        {
            var mediaStorageOptions = new CameraMediaStorageOptions
            {
                DefaultCamera = CameraDevice.Rear
            };
            var mediaFile = await _device.MediaPicker.TakePhotoAsync(mediaStorageOptions);

            _recognizedTextLabel.Text = "Loading..";
            return(mediaFile);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Takes the picture.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task with a return type of MediaFile.</returns>
        /// <exception cref="System.NotSupportedException">Throws an exception if feature is not supported.</exception>
        public Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            if (!IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            options.VerifyOptions();

            return(TakeMediaAsync("image/*", MediaStore.ActionImageCapture, options));
        }
Ejemplo n.º 13
0
        public async Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            var captureUI = new CameraCaptureUI();

            captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Png;
            var photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);

            if (photo == null)
            {
                return(null);
            }

            return(new MediaFile(photo.Name, () => photo.OpenStreamForReadAsync().Result));
        }
        /// <summary>
        /// Takes the picture.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task&lt;IMediaFile&gt;.</returns>
        /// <exception cref="InvalidOperationException">Only one operation can be active at a time</exception>
        /// <exception cref="System.NotImplementedException"></exception>
        public Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            options.VerifyOptions();

            var ntcs = new TaskCompletionSource <MediaFile>(options);

            if (Interlocked.CompareExchange(ref _completionSource, ntcs, null) != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            _cameraCapture.Show();

            return(ntcs.Task);
        }
        /// <summary>
        /// Takes the picture.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task&lt;IMediaFile&gt;.</returns>
        /// <exception cref="NotSupportedException">
        /// </exception>
        public Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            if (!IsPhotosSupported)
            {
                throw new NotSupportedException();
            }
            if (!IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            VerifyCameraOptions(options);

            return(GetMediaAsync(UIImagePickerControllerSourceType.Camera, TypeImage, options));
        }
        /// <summary>
        /// Takes the media asynchronous.
        /// </summary>
        /// <param name="type">The type of intent.</param>
        /// <param name="action">The action.</param>
        /// <param name="options">The options.</param>
        /// <returns>Task with a return type of MediaFile.</returns>
        /// <exception cref="System.InvalidOperationException">Only one operation can be active at a time.</exception>
        private Task <MediaFile> TakeMediaAsync(string type, string action, CameraMediaStorageOptions options)
        {
            // Create the completion source
            var id     = this.GetRequestId();
            var source = new TaskCompletionSource <MediaFile>(id);

            if (Interlocked.CompareExchange(ref this.completionSource, source, null) != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            // Start the media activity
            MediaPickerDroid.Context.StartActivity(this.CreateMediaIntent(id, type, action, options));

            // Set the media picked event handler
            EventHandler <MediaPickerActivity.MediaPickedEventArgs> handler = null;

            handler = (s, e) =>
            {
                // Remove the handler
                var taskCompletion = Interlocked.Exchange(ref this.completionSource, null);
                MediaPickerActivity.MediaPicked -= handler;

                // Validate the request identifier
                if (e.RequestId != id)
                {
                    return;
                }

                // Set the task result
                if (e.Error != null)
                {
                    taskCompletion.SetException(e.Error);
                }
                else if (e.IsCanceled)
                {
                    taskCompletion.SetCanceled();
                }
                else
                {
                    taskCompletion.SetResult(e.Media);
                }
            };

            // Register the handler
            MediaPickerActivity.MediaPicked += handler;
            return(source.Task);
        }
Ejemplo n.º 17
0
        public Task <MediaFile> SelectPhotoAsync(CameraMediaStorageOptions options)
        {
            var dlg = new OpenFileDialog {
                Title = "Select Photo For Task"
            };

            var result = dlg.ShowDialog();

            if (result == true)
            {
                var filename = dlg.FileName;
                return(Task.FromResult(new MediaFile(filename, () => File.OpenRead(filename))));
            }

            return(Task.FromResult <MediaFile>(null));
        }
Ejemplo n.º 18
0
        async void ScanTextBtn_Clicked(object sender, EventArgs e)
        {
            scanTextBtn.IsEnabled = false;
            mainPageBtn.IsEnabled = false;
            resultLabel.Text      = "Opening camera. Might take a while so please be patient!";
            originalPhoto.Source  = "";

            //tesseractille whitelist sallituista merkeistä
            //tesseractApi.SetVariable("tessedit_char_whitelist", "012345789()/-+*");

            //kameran käyttöön optiot HUOM! pienentäminen ei toimi näissä kuin windowsilla
            var options = new CameraMediaStorageOptions {
                DefaultCamera = CameraDevice.Rear
            };

            MediaFile picture = await mediaPicker.TakePhotoAsync(options);

            resultLabel.Text = "Processing image and recognizing text..";
            if (picture != null && picture.Source != null)
            {
                bool readSuccess = await imageParser.parseTextFromImageASync(picture);

                if (readSuccess)
                {
                    originalPhoto.Source = ImageSource.FromStream(() => picture.Source);

                    string calculation = imageParser.returnParsedText();

                    //tässä rajoitetaan laskutoimituksen pituus
                    if (calculation.Length <= 10)
                    {
                        //HUOM! tässä ei tarkisteta menevää stringiä mitenkään joten ohjelma kaatuu jos sinne pääsee mitäsattuu läpi
                        string result = CalculateString(calculation);
                        resultLabel.Text = calculation + " = " + result;
                    }

                    //jos ei saada järkevää stringiä luettua ts. siitä tulee aivan liian pitkä niin =>
                    else
                    {
                        resultLabel.Text = "OCR result unclear, please try again.";
                    }
                }
            }
            scanTextBtn.IsEnabled = true;
            mainPageBtn.IsEnabled = true;
            scanTextBtn.Text      = "Calculate again";
        }
Ejemplo n.º 19
0
        public async Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            m_photo = await m_captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);

            m_Stream = await m_photo.OpenStreamForReadAsync();

            //   Func<string, string> convert = delegate (string s)
            // { return s.ToUpper(); };
            Func <Stream> conv = new Func <Stream>(getStream);///({ return await m_photo.OpenStreamForReadAsync(); };
            MediaFile     p    = new MediaFile(m_photo.Path, conv);

            if (m_photo == null)
            {
                // User cancelled photo capture
                return(null);
            }
            return(p);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MediaPickerDelegate"/> class.
        /// </summary>
        /// <param name="viewController">The view controller.</param>
        /// <param name="sourceType">Type of the source.</param>
        /// <param name="options">The options.</param>
        internal MediaPickerDelegate(
            UIViewController viewController,
            UIImagePickerControllerSourceType sourceType,
            CameraMediaStorageOptions options)
        {
            // Setup the current media picker delegate
            this.viewController = viewController;
            this.source         = sourceType;
            this.options        = options ?? new CameraMediaStorageOptions();

            // Add the observer
            if (viewController != null)
            {
                UIDevice.CurrentDevice.BeginGeneratingDeviceOrientationNotifications();
                this.observer = NSNotificationCenter.DefaultCenter.AddObserver(
                    UIDevice.OrientationDidChangeNotification,
                    this.DidRotate);
            }
        }
Ejemplo n.º 21
0
        public async Task <MediaFile> SelectPhotoAsync(CameraMediaStorageOptions options)
        {
            var picker = new FileOpenPicker();

            picker.ViewMode = PickerViewMode.Thumbnail;
            picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            picker.FileTypeFilter.Add(".png");
            picker.FileTypeFilter.Add(".jpg");
            picker.FileTypeFilter.Add(".jpeg");

            var file = await picker.PickSingleFileAsync();

            if (file != null)
            {
                return(new MediaFile(file.Name, () => file.OpenStreamForReadAsync().Result));
            }

            return(null);
        }
Ejemplo n.º 22
0
        public async Task <MediaFile> TakePicture()
        {
            var cmso = new CameraMediaStorageOptions
            {
                DefaultCamera      = CameraDevice.Rear,
                SaveMediaOnCapture = false
            };

            return(await m_MediaPicker.TakePhotoAsync(cmso).ContinueWith(t =>
            {
                if (t.IsCompleted &&
                    t.Status == TaskStatus.RanToCompletion)
                {
                    var mediaFile = t.Result;
                    return mediaFile;
                }

                return null;
            }, m_Scheduler));
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Verifies the camera options.
        /// </summary>
        /// <param name="options">The camera options.</param>
        private static void VerifyCameraOptions(CameraMediaStorageOptions options)
        {
            // If options are not specified
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // If path is rooted
            if ((options.Directory != null) && Path.IsPathRooted(options.Directory))
            {
                // ReSharper disable once LocalizableElement
                throw new ArgumentException("Directory must be a relative path", nameof(options));
            }

            // Validate the camera options
            if (!Enum.IsDefined(typeof(CameraDevice), options.DefaultCamera))
            {
                throw new ArgumentException("Camera is not a member of CameraDevice");
            }
        }
Ejemplo n.º 24
0
        public void AddImage(string fakeImagePath, int cropSize)
        {
            Task <MediaFile> imageTask = null;
            var options = new CameraMediaStorageOptions
            {
                DefaultCamera     = CameraDevice.Rear,
                MaxPixelDimension = 400,
            };

            imageTask = AppProvider.MediaPicker.SelectPhotoAsync(options);

            imageTask.ContinueWith(delegate(Task <MediaFile> arg) {
                MediaFile file = arg.Result;

                if (file != null)
                {
                    AppProvider.IOManager.DeleteFile(fakeImagePath);
                    AppProvider.ImageService.CropAndResizeImage(file.Path, fakeImagePath, cropSize);
                    OnImageChanged();
                }
            });
        }
        async void AnalyzeAction()
        {
            try
            {
                //TODO:check if camera etc os available media.phot etc.

                var options = new CameraMediaStorageOptions()
                {
                    SaveMediaOnCapture = false,
                };
                var result = await mediaPicker.TakePhotoAsync(options);

                var data = receiptAnalyser.Analyse(result.Source);
                ShoppingItems = new ObservableCollection <ShoppingItem>(data);
                ;
            }
            catch (Exception ex)
            {
                logger.Log(ex.Message + ex.StackTrace, Category.Exception, Priority.Medium);
                await pageDialogService.DisplayAlertAsync(locale.RUnknownErrorTitle, locale.RUnknonwnMessage, locale.RUnknownErrorConfirm);
            }
        }
        /// <summary>
        /// Takes the picture.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task representing the asynchronous operation.</returns>
        /// <exception cref="NotSupportedException">No camera is present on the current device.</exception>
        public override Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            // If no camera available
            if (!this.IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            // Validate options
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // If path is rooted
            if (Path.IsPathRooted(options.Directory))
            {
                throw new ArgumentException("options.Directory must be a relative folder");
            }

            // Take the photo
            return(this.TakeMediaAsync("image/*", MediaStore.ActionImageCapture, options));
        }
Ejemplo n.º 27
0
        /////// <summary>
        /////// Select a picture from library.
        /////// </summary>
        /////// <param name="options">The storage options.</param>
        /////// <returns>Task representing the asynchronous operation.</returns>
        ////public Task<MediaFile> SelectPhotoAsync(CameraMediaStorageOptions options)
        ////{
        ////    // If photos are not supported
        ////    if (!this.IsPhotosSupported)
        ////    {
        ////        throw new NotSupportedException();
        ////    }

        ////    // Get the image from pictures
        ////    return this.GetMediaAsync(UIImagePickerControllerSourceType.PhotoLibrary, MediaPickerIOS.TypeImage);
        ////}

        /// <summary>
        /// Takes the picture.
        /// </summary>
        /// <param name="options">The storage options.</param>
        /// <returns>Task representing the asynchronous operation.</returns>
        public override Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
        {
            // If photos are not supported
            if (!this.IsPhotosSupported)
            {
                throw new NotSupportedException();
            }

            // If camera is not supported
            if (!this.IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            // If the camera permission is not determined
            var status = AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video);

            if (status == AVAuthorizationStatus.NotDetermined)
            {
                var granted = AVCaptureDevice.RequestAccessForMediaTypeAsync(AVMediaType.Video);
                granted.Wait();
                if (!granted.Result)
                {
                    return(null);
                }
            }

            // If camera is restricted
            if ((status == AVAuthorizationStatus.Denied) || (status == AVAuthorizationStatus.Restricted))
            {
                return(null);
            }

            // Take the camera photo
            MediaPickerIOS.VerifyCameraOptions(options);
            return(this.GetMediaAsync(UIImagePickerControllerSourceType.Camera, MediaPickerIOS.TypeImage, options));
        }
Ejemplo n.º 28
0
 public Task <MediaFile> TakePhotoAsync(CameraMediaStorageOptions options)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 29
0
        /// <summary>
        /// Gets the media asynchronous.
        /// </summary>
        /// <param name="sourceType">Type of the source.</param>
        /// <param name="mediaType">Type of the media.</param>
        /// <param name="options">The options.</param>
        /// <returns>Task representing the asynchronous operation.</returns>
        private Task <MediaFile> GetMediaAsync(
            UIImagePickerControllerSourceType sourceType,
            string mediaType,
            CameraMediaStorageOptions options = null)
        {
            // Get the active window
            var window = UIApplication.SharedApplication.KeyWindow;

            if (window == null)
            {
                throw new InvalidOperationException("There's no current active window");
            }

            // Get the view controller
            var viewController = window.RootViewController;

#if __IOS_10__
            if (viewController == null || (viewController.PresentedViewController != null && viewController.PresentedViewController.GetType() == typeof(UIAlertController)))
            {
                window =
                    UIApplication.SharedApplication.Windows.OrderByDescending(w => w.WindowLevel)
                    .FirstOrDefault(w => w.RootViewController != null);

                if (window == null)
                {
                    throw new InvalidOperationException("Could not find current view controller");
                }

                viewController = window.RootViewController;
            }
#endif

            // Get the root view controller
            while (viewController.PresentedViewController != null)
            {
                viewController = viewController.PresentedViewController;
            }

            // Create a new media picker delegate
            var newDelegate     = new MediaPickerDelegate(viewController, sourceType, options);
            var operationResult = Interlocked.CompareExchange(ref this.pickerDelegate, newDelegate, null);
            if (operationResult != null)
            {
                throw new InvalidOperationException("Only one operation can be active at at time");
            }

            // Setup the view controller
            var picker = MediaPickerIOS.SetupController(newDelegate, sourceType, mediaType, options);

            // If the image is from photo library
            if ((UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad) &&
                (sourceType == UIImagePickerControllerSourceType.PhotoLibrary))
            {
                // Create a photo choosing popover
                newDelegate.Popover = new UIPopoverController(picker)
                {
                    Delegate = new MediaPickerPopoverDelegate(newDelegate, picker)
                };
                newDelegate.DisplayPopover();
            }
            else
            {
                // Show the media picker view
                viewController.PresentViewController(picker, true, null);
            }

            // Get the media
            return(newDelegate.Task.ContinueWith(
                       t =>
            {
                // Dispose popover if any
                if (this.popover != null)
                {
                    this.popover.Dispose();
                    this.popover = null;
                }

                // Release the media picker delegate
                Interlocked.Exchange(ref this.pickerDelegate, null);
                return t;
            }).Unwrap());
        }