コード例 #1
0
        private MediaFile GetPictureMediaFile(ALAsset asset, long index = 0)
        {
            var rep = asset.DefaultRepresentation;

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

            var cgImage = rep.GetImage();

            UIImage image = null;

            if (cgImage == null)
            {
                var fetch     = PHAsset.FetchAssets(new[] { asset.AssetUrl }, null);
                var ph        = fetch.firstObject as PHAsset;
                var manager   = PHImageManager.DefaultManager;
                var phOptions = new PHImageRequestOptions
                {
                    Version = PHImageRequestOptionsVersion.Original,
                    NetworkAccessAllowed = true,
                    Synchronous          = true
                };

                phOptions.ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary info) =>
                {
                    Debug.WriteLine($"Progress: {progress.ToString()}");

                    stop = false;
                };

                manager.RequestImageData(ph, phOptions, (data, i, orientation, k) =>
                {
                    if (data != null)
                    {
                        image = new UIImage(data, 1.0f);
                    }
                });
                phOptions?.Dispose();
                fetch?.Dispose();
                ph?.Dispose();
            }
            else
            {
                image = new UIImage(cgImage, 1.0f, (UIImageOrientation)rep.Orientation);
            }

            var path = MediaPickerDelegate.GetOutputPath(MediaImplementation.TypeImage,
                                                         options.Directory ?? "temp",
                                                         options.Name, asset.AssetUrl?.PathExtension, index);

            cgImage?.Dispose();
            cgImage = null;
            rep?.Dispose();
            rep = null;

            //There might be cases when the original image cannot be retrieved while image thumb was still present.
            //Then no need to try to save it as we will get an exception here
            //TODO: Ideally, we should notify the client that we failed to get original image
            //TODO: Otherwise, it might be confusing to the user, that he saw the thumb, but did not get the image
            if (image == null)
            {
                return(null);
            }

            image.AsJPEG().Save(path, true);

            image?.Dispose();
            image = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Default);

            string aPath = null;
            //try to get the album path's url
            var url = asset.AssetUrl;

            aPath = url?.AbsoluteString;

            return(new MediaFile(path, () => File.OpenRead(path), albumPath: aPath));
        }
コード例 #2
0
 internal MediaPickerPopoverDelegate(MediaPickerDelegate pickerDelegate, UIImagePickerController picker)
 {
     pickerDelegate = pickerDelegate;
     picker = picker;
 }
コード例 #3
0
        static void ResizeAndCompressImage(StoreCameraMediaOptions options, MediaFile mediaFile, string pathExtension)
        {
            var image   = UIImage.FromFile(mediaFile.Path);
            var percent = 1.0f;

            if (options.PhotoSize != PhotoSize.Full)
            {
                try
                {
                    switch (options.PhotoSize)
                    {
                    case PhotoSize.Large:
                        percent = .75f;
                        break;

                    case PhotoSize.Medium:
                        percent = .5f;
                        break;

                    case PhotoSize.Small:
                        percent = .25f;
                        break;

                    case PhotoSize.Custom:
                        percent = (float)options.CustomPhotoSize / 100f;
                        break;
                    }

                    if (options.PhotoSize == PhotoSize.MaxWidthHeight && options.MaxWidthHeight.HasValue)
                    {
                        var max = Math.Max(image.Size.Width, image.Size.Height);
                        if (max > options.MaxWidthHeight.Value)
                        {
                            percent = (float)options.MaxWidthHeight.Value / (float)max;
                        }
                    }

                    if (percent < 1.0f)
                    {
                        //begin resizing image
                        image = image.ResizeImageWithAspectRatio(percent);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Unable to compress image: {ex}");
                }
            }
            NSDictionary meta = null;

            if (options.SaveMetaData)
            {
                try
                {
                    meta = PhotoLibraryAccess.GetPhotoLibraryMetadata(new NSUrl(mediaFile.AlbumPath));
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Unable to get metadata: {ex}");
                }
            }
            //iOS quality is 0.0-1.0
            var quality    = (options.CompressionQuality / 100f);
            var savedImage = false;

            if (meta != null)
            {
                savedImage = MediaPickerDelegate.SaveImageWithMetadata(image, quality, meta, mediaFile.Path, pathExtension);
            }

            if (!savedImage)
            {
                if (pathExtension == "png")
                {
                    image.AsPNG().Save(mediaFile.Path, true);
                }
                else
                {
                    image.AsJPEG(quality).Save(mediaFile.Path, true);
                }
            }

            image?.Dispose();
            image = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
        }
コード例 #4
0
        private Task <MediaFile> GetMediaAsync(UIImagePickerControllerSourceType sourceType, string mediaType, StoreCameraMediaOptions options = null, CancellationToken token = default(CancellationToken))
        {
            UIViewController viewController = null;
            UIWindow         window         = UIApplication.SharedApplication.KeyWindow;

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

            if (window.WindowLevel == UIWindowLevel.Normal)
            {
                viewController = window.RootViewController;
            }

            if (viewController == null)
            {
                window = UIApplication.SharedApplication.Windows.OrderByDescending(w => w.WindowLevel).FirstOrDefault(w => w.RootViewController != null && w.WindowLevel == UIWindowLevel.Normal);
                if (window == null)
                {
                    throw new InvalidOperationException("Could not find current view controller");
                }
                else
                {
                    viewController = window.RootViewController;
                }
            }

            while (viewController.PresentedViewController != null)
            {
                viewController = viewController.PresentedViewController;
            }

            if (token.IsCancellationRequested)
            {
                return(Task.FromResult((MediaFile)null));
            }

            MediaPickerDelegate ndelegate = new MediaPickerDelegate(viewController, sourceType, options, token);
            var od = Interlocked.CompareExchange(ref pickerDelegate, ndelegate, null);

            if (od != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            var picker = SetupController(ndelegate, sourceType, mediaType, options);

            if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad && sourceType == UIImagePickerControllerSourceType.PhotoLibrary)
            {
                ndelegate.Popover          = popover = new UIPopoverController(picker);
                ndelegate.Popover.Delegate = new MediaPickerPopoverDelegate(ndelegate, picker);
                ndelegate.DisplayPopover();

                token.Register(() =>
                {
                    if (popover == null)
                    {
                        return;
                    }
                    NSRunLoop.Main.BeginInvokeOnMainThread(() =>
                    {
                        ndelegate.Popover.Dismiss(true);
                        ndelegate.CancelTask();
                    });
                });
            }
            else
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
                {
                    picker.ModalPresentationStyle = options?.ModalPresentationStyle == MediaPickerModalPresentationStyle.OverFullScreen
                                ? UIModalPresentationStyle.OverFullScreen
                                : UIModalPresentationStyle.FullScreen;
                }
                viewController.PresentViewController(picker, true, null);

                token.Register(() =>
                {
                    if (picker == null)
                    {
                        return;
                    }

                    NSRunLoop.Main.BeginInvokeOnMainThread(() =>
                    {
                        picker.DismissModalViewController(true);
                        ndelegate.CancelTask();
                    });
                });
            }

            return(ndelegate.Task.ContinueWith(t =>
            {
                try
                {
                    popover?.Dispose();
                }
                catch
                {
                }
                popover = null;


                Interlocked.Exchange(ref pickerDelegate, null);

                try
                {
                    picker?.Dispose();
                }
                catch
                {
                }
                picker = null;
                return t;
            }).Unwrap());
        }
コード例 #5
0
 internal MediaPickerController(MediaPickerDelegate mpDelegate)
 {
     base.Delegate = mpDelegate;
 }
コード例 #6
0
        Task <MediaFile> GetMediaAsync(UIImagePickerControllerSourceType sourceType, string mediaType, StoreCameraMediaOptions options = null, CancellationToken token = default(CancellationToken))
        {
            var viewController = GetHostViewController();

            if (token.IsCancellationRequested)
            {
                return(Task.FromResult((MediaFile)null));
            }

            var ndelegate = new MediaPickerDelegate(viewController, sourceType, options, token);
            var od        = Interlocked.CompareExchange(ref pickerDelegate, ndelegate, null);

            if (od != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            var tcs = new TaskCompletionSource <Task>();

            var picker = SetupController(ndelegate, sourceType, mediaType, tcs, options);

            tcs.Task.ContinueWith(t => Dismiss(popover, picker));

            if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad && sourceType == UIImagePickerControllerSourceType.PhotoLibrary)
            {
                ndelegate.Popover          = popover = new UIPopoverController(picker);
                ndelegate.Popover.Delegate = new MediaPickerPopoverDelegate(ndelegate, picker);
                ndelegate.DisplayPopover();

                token.Register(() =>
                {
                    if (popover == null)
                    {
                        return;
                    }
                    NSRunLoop.Main.BeginInvokeOnMainThread(() =>
                    {
                        ndelegate.Popover.Dismiss(true);
                        ndelegate.CancelTask();
                    });
                });
            }
            else
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
                {
                    picker.ModalPresentationStyle = options?.ModalPresentationStyle == MediaPickerModalPresentationStyle.OverFullScreen
                                                ? UIModalPresentationStyle.OverFullScreen
                                                : UIModalPresentationStyle.FullScreen;
                }
                viewController.PresentViewController(picker, true, null);

                token.Register(() =>
                {
                    if (picker == null)
                    {
                        return;
                    }

                    NSRunLoop.Main.BeginInvokeOnMainThread(() =>
                    {
                        picker.DismissModalViewController(true);
                        ndelegate.CancelTask();
                    });
                });
            }

            return(ndelegate.Task.ContinueWith(t => t.Result == null ? null : t.Result.FirstOrDefault()));
        }
コード例 #7
0
 internal MediaPickerController(MediaPickerDelegate mpDelegate) =>
 base.Delegate = mpDelegate;
コード例 #8
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public MediaPickerController GetTakeVideoUI(StoreVideoOptions options)
        {
            if (!IsTakeVideoSupported)
                throw new NotSupportedException();
            if (!IsCameraAvailable)
                throw new NotSupportedException();

            VerifyCameraOptions(options);

            var d = new MediaPickerDelegate(null, UIImagePickerControllerSourceType.Camera, options);
            return SetupController(d, UIImagePickerControllerSourceType.Camera, TypeMovie, options);
        }
コード例 #9
0
 internal MediaPickerController(MediaPickerDelegate mpDelegate, TaskCompletionSource <Task> taskCompletionSource)
 {
     base.Delegate             = mpDelegate;
     this.taskCompletionSource = taskCompletionSource;
 }
コード例 #10
0
        private static void ResizeAndCompressImage(StoreCameraMediaOptions options, MediaFile mediaFile, string pathExtension)
        {
            var image   = UIImage.FromFile(mediaFile.Path);
            var percent = 1.0f;

            if (options.PhotoSize != PhotoSize.Full)
            {
                try
                {
                    switch (options.PhotoSize)
                    {
                    case PhotoSize.Large:
                        percent = .75f;
                        break;

                    case PhotoSize.Medium:
                        percent = .5f;
                        break;

                    case PhotoSize.Small:
                        percent = .25f;
                        break;

                    case PhotoSize.Custom:
                        percent = (float)options.CustomPhotoSize / 100f;
                        break;
                    }

                    if (options.PhotoSize == PhotoSize.MaxWidthHeight && options.MaxWidthHeight.HasValue)
                    {
                        var max = Math.Max(image.Size.Width, image.Size.Height);
                        if (max > options.MaxWidthHeight.Value)
                        {
                            percent = (float)options.MaxWidthHeight.Value / (float)max;
                        }
                    }

                    if (percent < 1.0f)
                    {
                        //begin resizing image
                        image = image.ResizeImageWithAspectRatio(percent);
                    }

                    NSDictionary meta = null;
                    try
                    {
                        //meta = PhotoLibraryAccess.GetPhotoLibraryMetadata(asset.AssetUrl);

                        //meta = info[UIImagePickerController.MediaMetadata] as NSDictionary;
                        if (meta != null && meta.ContainsKey(ImageIO.CGImageProperties.Orientation))
                        {
                            var newMeta = new NSMutableDictionary();
                            newMeta.SetValuesForKeysWithDictionary(meta);
                            var newTiffDict = new NSMutableDictionary();
                            newTiffDict.SetValuesForKeysWithDictionary(meta[ImageIO.CGImageProperties.TIFFDictionary] as NSDictionary);
                            newTiffDict.SetValueForKey(meta[ImageIO.CGImageProperties.Orientation], ImageIO.CGImageProperties.TIFFOrientation);
                            newMeta[ImageIO.CGImageProperties.TIFFDictionary] = newTiffDict;

                            meta = newMeta;
                        }
                        var location = options.Location;
                        if (meta != null && location != null)
                        {
                            meta = MediaPickerDelegate.SetGpsLocation(meta, location);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Unable to get metadata: {ex}");
                    }

                    //iOS quality is 0.0-1.0
                    var quality    = (options.CompressionQuality / 100f);
                    var savedImage = false;
                    if (meta != null)
                    {
                        savedImage = MediaPickerDelegate.SaveImageWithMetadata(image, quality, meta, mediaFile.Path, pathExtension);
                    }

                    if (!savedImage)
                    {
                        image.AsJPEG(quality).Save(mediaFile.Path, true);
                    }

                    image?.Dispose();

                    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Unable to compress image: {ex}");
                }
            }
        }
コード例 #11
0
 internal MediaPickerPopoverDelegate(MediaPickerDelegate pickerDelegate, UINavigationController picker)
 {
     this.pickerDelegate = pickerDelegate;
     this.picker         = picker;
 }
コード例 #12
0
        private Task<MediaFile> GetMediaAsync(UIImagePickerControllerSourceType sourceType, string mediaType, StoreCameraMediaOptions options = null)
        {
            UIWindow window = UIApplication.SharedApplication.KeyWindow;
            if (window == null)
                throw new InvalidOperationException("There's no current active window");

            UIViewController viewController = window.RootViewController;

            if (viewController == null)
            {
                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");
                else
                    viewController = window.RootViewController;
            }

            while (viewController.PresentedViewController != null)
                viewController = viewController.PresentedViewController;

            MediaPickerDelegate ndelegate = new MediaPickerDelegate(viewController, sourceType, options);
            var od = Interlocked.CompareExchange(ref pickerDelegate, ndelegate, null);
            if (od != null)
                throw new InvalidOperationException("Only one operation can be active at at time");

            var picker = SetupController(ndelegate, sourceType, mediaType, options);

            if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad && sourceType == UIImagePickerControllerSourceType.PhotoLibrary)
            {
                ndelegate.Popover = new UIPopoverController(picker);
                ndelegate.Popover.Delegate = new MediaPickerPopoverDelegate(ndelegate, picker);
                ndelegate.DisplayPopover();
            }
            else
                viewController.PresentViewController(picker, true, null);

            return ndelegate.Task.ContinueWith(t =>
            {
                if (popover != null)
                {
                    popover.Dispose();
                    popover = null;
                }

                Interlocked.Exchange(ref pickerDelegate, null);
                return t;
            }).Unwrap();
        }
コード例 #13
0
        private static MediaPickerController SetupController(MediaPickerDelegate mpDelegate, UIImagePickerControllerSourceType sourceType, string mediaType, StoreCameraMediaOptions options = null)
        {
            var picker = new MediaPickerController(mpDelegate);
            picker.MediaTypes = new[] { mediaType };
            picker.SourceType = sourceType;

            if (sourceType == UIImagePickerControllerSourceType.Camera)
            {
                picker.CameraDevice = GetUICameraDevice(options.DefaultCamera);

                if (mediaType == TypeImage)
                    picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Photo;
                else if (mediaType == TypeMovie)
                {
                    StoreVideoOptions voptions = (StoreVideoOptions)options;

                    picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Video;
                    picker.VideoQuality = GetQuailty(voptions.Quality);
                    picker.VideoMaximumDuration = voptions.DesiredLength.TotalSeconds;
                }
            }

            return picker;
        }
コード例 #14
0
 internal MediaPickerPopoverDelegate(MediaPickerDelegate pickerDelegate, UIImagePickerController picker)
 {
     this.pickerDelegate = pickerDelegate;
     this.picker         = picker;
 }
コード例 #15
0
        private MediaFile GetPictureMediaFile(ALAsset asset)
        {
            var rep = asset.DefaultRepresentation;

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

            var cgImage = rep.GetImage();

            var path = MediaPickerDelegate.GetOutputPath(MediaImplementation.TypeImage,
                                                         _options.Directory ?? "temp",
                                                         _options.Name);

            var image = new UIImage(cgImage, 1.0f, (UIImageOrientation)rep.Orientation);

            var percent = 1.0f;

            if (_options.PhotoSize != PhotoSize.Full)
            {
                try
                {
                    switch (_options.PhotoSize)
                    {
                    case PhotoSize.Large:
                        percent = .75f;
                        break;

                    case PhotoSize.Medium:
                        percent = .5f;
                        break;

                    case PhotoSize.Small:
                        percent = .25f;
                        break;

                    case PhotoSize.Custom:
                        percent = (float)_options.CustomPhotoSize / 100f;
                        break;
                    }

                    if (_options.PhotoSize == PhotoSize.MaxWidthHeight && _options.MaxWidthHeight.HasValue)
                    {
                        var max = Math.Max(image.CGImage.Width, image.CGImage.Height);
                        if (max > _options.MaxWidthHeight.Value)
                        {
                            percent = (float)_options.MaxWidthHeight.Value / (float)max;
                        }
                    }

                    if (percent < 1.0f)
                    {
                        //begin resizing image
                        image = image.ResizeImageWithAspectRatio(percent);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Unable to compress image: {ex}");
                }
            }


            NSDictionary meta = null;

            try
            {
                //meta = PhotoLibraryAccess.GetPhotoLibraryMetadata(asset.AssetUrl);

                //meta = info[UIImagePickerController.MediaMetadata] as NSDictionary;
                if (meta != null && meta.ContainsKey(ImageIO.CGImageProperties.Orientation))
                {
                    var newMeta = new NSMutableDictionary();
                    newMeta.SetValuesForKeysWithDictionary(meta);
                    var newTiffDict = new NSMutableDictionary();
                    newTiffDict.SetValuesForKeysWithDictionary(meta[ImageIO.CGImageProperties.TIFFDictionary] as NSDictionary);
                    newTiffDict.SetValueForKey(meta[ImageIO.CGImageProperties.Orientation], ImageIO.CGImageProperties.TIFFOrientation);
                    newMeta[ImageIO.CGImageProperties.TIFFDictionary] = newTiffDict;

                    meta = newMeta;
                }
                var location = _options.Location;
                if (meta != null && location != null)
                {
                    meta = MediaPickerDelegate.SetGpsLocation(meta, location);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Unable to get metadata: {ex}");
            }

            //iOS quality is 0.0-1.0
            var quality    = (_options.CompressionQuality / 100f);
            var savedImage = false;

            if (meta != null)
            {
                savedImage = MediaPickerDelegate.SaveImageWithMetadata(image, quality, meta, path);
            }

            if (!savedImage)
            {
                image.AsJPEG(quality).Save(path, true);
            }


            string aPath = null;
            //try to get the album path's url
            var url = asset.AssetUrl;

            aPath = url?.AbsoluteString;

            return(new MediaFile(path, () => File.OpenRead(path), albumPath: aPath));
        }
コード例 #16
0
        private Task <MediaFile> GetMediaAsync(UIImagePickerControllerSourceType sourceType, string mediaType, StoreCameraMediaOptions options = null)
        {
            UIViewController viewController = null;
            UIWindow         window         = UIApplication.SharedApplication.KeyWindow;

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

            if (window.WindowLevel == UIWindowLevel.Normal)
            {
                viewController = window.RootViewController;
            }

            if (viewController == null)
            {
                window = UIApplication.SharedApplication.Windows.OrderByDescending(w => w.WindowLevel).FirstOrDefault(w => w.RootViewController != null && w.WindowLevel == UIWindowLevel.Normal);
                if (window == null)
                {
                    throw new InvalidOperationException("Could not find current view controller");
                }
                else
                {
                    viewController = window.RootViewController;
                }
            }

            while (viewController.PresentedViewController != null)
            {
                viewController = viewController.PresentedViewController;
            }

            MediaPickerDelegate ndelegate = new MediaPickerDelegate(viewController, sourceType, options);
            var od = Interlocked.CompareExchange(ref pickerDelegate, ndelegate, null);

            if (od != null)
            {
                throw new InvalidOperationException("Only one operation can be active at at time");
            }

            var picker = SetupController(ndelegate, sourceType, mediaType, options);

            if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad && sourceType == UIImagePickerControllerSourceType.PhotoLibrary)
            {
                ndelegate.Popover          = popover = new UIPopoverController(picker);
                ndelegate.Popover.Delegate = new MediaPickerPopoverDelegate(ndelegate, picker);
                ndelegate.DisplayPopover();
            }
            else
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
                {
                    picker.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
                }
                viewController.PresentViewController(picker, true, null);
            }

            return(ndelegate.Task.ContinueWith(t =>
            {
                if (popover != null)
                {
                    popover.Dispose();
                    popover = null;
                }

                Interlocked.Exchange(ref pickerDelegate, null);

                picker.Dispose();
                return t;
            }).Unwrap());
        }
コード例 #17
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public MediaPickerController GetPickVideoUI()
        {
            if (!IsPickVideoSupported)
                throw new NotSupportedException();

            var d = new MediaPickerDelegate(null, UIImagePickerControllerSourceType.PhotoLibrary, null);
            return SetupController(d, UIImagePickerControllerSourceType.PhotoLibrary, TypeMovie);
        }