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)); }
internal MediaPickerPopoverDelegate(MediaPickerDelegate pickerDelegate, UIImagePickerController picker) { pickerDelegate = pickerDelegate; picker = picker; }
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); }
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()); }
internal MediaPickerController(MediaPickerDelegate mpDelegate) { base.Delegate = mpDelegate; }
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())); }
internal MediaPickerController(MediaPickerDelegate mpDelegate) => base.Delegate = mpDelegate;
/// <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); }
internal MediaPickerController(MediaPickerDelegate mpDelegate, TaskCompletionSource <Task> taskCompletionSource) { base.Delegate = mpDelegate; this.taskCompletionSource = taskCompletionSource; }
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}"); } } }
internal MediaPickerPopoverDelegate(MediaPickerDelegate pickerDelegate, UINavigationController picker) { this.pickerDelegate = pickerDelegate; this.picker = picker; }
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(); }
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; }
internal MediaPickerPopoverDelegate(MediaPickerDelegate pickerDelegate, UIImagePickerController picker) { this.pickerDelegate = pickerDelegate; this.picker = picker; }
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)); }
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()); }
/// <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); }