private async void FinishedPickingAssets(object sender, MultiAssetEventArgs args)
        {
            var results = new List <MediaFile>(24);
            var tcs     = new TaskCompletionSource <IList <MediaFile> >();

            Debug.WriteLine("User finished picking assets. {0} items selected.", args.Assets.Length);

            _preselectedAssets = args.Assets;

            // For demo purposes: just show all chosen pictures in order every second
            foreach (var asset in _preselectedAssets)
            {
                // Get information about the asset, e.g. file patch
                asset.RequestContentEditingInput(new PHContentEditingInputRequestOptions(),
                                                 completionHandler: (input, options) =>
                {
                    var path = input.FullSizeImageUrl.ToString();
                    path     = path.Replace("file://", "");

                    var fileName        = System.IO.Path.GetFileNameWithoutExtension(path);
                    var ext             = System.IO.Path.GetExtension(path);
                    var imgOption       = MediaFileGetImageOptions.CreateDefaultThumb();
                    var thumbImageBytes = AssetImageService.GetImageBytes(asset, imgOption);

                    var thumbnailImagePath =
                        MediaFileHelper.GetOutputPath(MediaFileType.Image, "TmpMedia",
                                                      $"{fileName}-THUMBNAIL{ext}");
                    System.IO.File.WriteAllBytes(thumbnailImagePath, thumbImageBytes);

                    results.Add(new MediaFile
                    {
                        Path        = path,
                        PreviewPath = thumbnailImagePath,
                        Type        = MediaFileType.Image
                    });
                });

                await Task.Delay(250);
            }

            tcs.TrySetResult(results);
            _mediaPickTcs?.TrySetResult(await tcs.Task);
            _preselectedAssets = null;
        }
        public async Task <string> CreatePreviewPath(string path, string type)
        {
            await Task.Delay(TimeSpan.FromMilliseconds(100));

            var fileName = System.IO.Path.GetFileNameWithoutExtension(path);
            var ext      = System.IO.Path.GetExtension(path);

            var strs        = path.Split('/');
            var assetResult = PHAsset.FetchAssetsUsingLocalIdentifiers(strs, null);
            var asset       = assetResult.firstObject as PHAsset;

            var thumbImageBytes =
                AssetImageService.GetImageBytes(asset, MediaFileGetImageOptions.CreateDefaultThumb());

            var thumbnailImagePath =
                MediaFileHelper.GetOutputPath(MediaFileType.Image, "TmpMedia",
                                              $"{fileName}-THUMBNAIL{ext}");

            System.IO.File.WriteAllBytes(thumbnailImagePath, thumbImageBytes);

            return(thumbnailImagePath);
        }
        internal static byte[] GetImageBytes(PHAsset asset, MediaFileGetImageOptions options)
        {
            nfloat w = options.Width;
            nfloat h = options.Height;

            switch (options.Orientation)
            {
            case MediaFileImageOrientation.Left:
            case MediaFileImageOrientation.LeftMirrored:
            case MediaFileImageOrientation.Right:
            case MediaFileImageOrientation.RightMirrored:
                var wT = w;
                w = h;
                h = wT;
                break;
            }

            if (w <= 0)
            {
                if (h > 0)
                {
                    w = asset.PixelWidth * h / asset.PixelHeight;
                }
                else
                {
                    w = asset.PixelWidth;
                }
            }

            if (h <= 0)
            {
                h = asset.PixelHeight * w / asset.PixelWidth;
            }

            byte[] imageBytes = null;

            PHImageManager.DefaultManager.RequestImageForAsset(
                asset,
                new CoreGraphics.CGSize(w, h),
                ImageResizeAspectToPH(options.ResizeAspect),
                new PHImageRequestOptions {
                Synchronous = true, ResizeMode = PHImageRequestOptionsResizeMode.Exact
            },
                (requestedImage, info) =>
            {
                if (options.Orientation != MediaFileImageOrientation.Up ||
                    requestedImage.Size.Width != w ||
                    requestedImage.Size.Height != h)
                {
                    var destW = w;
                    var destH = h;

                    if (options.ResizeAspect == MediaFileGetImageOptions.ImageResizeAspect.AspectFit)
                    {
                        var widthScale  = w / requestedImage.Size.Width;
                        var heightScale = h / requestedImage.Size.Height;
                        var scale       = (nfloat)Math.Min(widthScale, heightScale);

                        switch (options.Orientation)
                        {
                        case MediaFileImageOrientation.Left:
                        case MediaFileImageOrientation.LeftMirrored:
                        case MediaFileImageOrientation.Right:
                        case MediaFileImageOrientation.RightMirrored:
                            h     = requestedImage.Size.Width * scale;
                            w     = requestedImage.Size.Height * scale;
                            destW = h;
                            destH = w;
                            break;

                        default:
                            w     = requestedImage.Size.Width * scale;
                            h     = requestedImage.Size.Height * scale;
                            destW = w;
                            destH = h;
                            break;
                        }
                    }
                    else
                    {
                        switch (options.Orientation)
                        {
                        case MediaFileImageOrientation.Left:
                        case MediaFileImageOrientation.LeftMirrored:
                        case MediaFileImageOrientation.Right:
                        case MediaFileImageOrientation.RightMirrored:
                            var wT = w;
                            w      = h;
                            h      = wT;
                            break;
                        }
                    }

                    var cg          = requestedImage.CGImage;
                    int bytesPerRow = (int)w * 4;
                    var ctx         = new CoreGraphics.CGBitmapContext(null, (int)w, (int)h, 8, bytesPerRow,
                                                                       cg.ColorSpace, CoreGraphics.CGImageAlphaInfo.PremultipliedLast);

                    Func <float, float> radians = (degrees) => { return(degrees * ((float)Math.PI / 180f)); };

                    switch (options.Orientation)
                    {
                    case MediaFileImageOrientation.UpMirrored:
                        ctx.TranslateCTM(w, 0);
                        ctx.ScaleCTM(-1f, 1f);
                        break;

                    case MediaFileImageOrientation.Down:
                        ctx.TranslateCTM(w, h);
                        ctx.RotateCTM(radians(180f));
                        break;

                    case MediaFileImageOrientation.DownMirrored:
                        ctx.TranslateCTM(0, h);
                        ctx.RotateCTM(radians(180f));
                        ctx.ScaleCTM(-1f, 1f);
                        break;

                    case MediaFileImageOrientation.Left:
                        ctx.TranslateCTM(w, 0);
                        ctx.RotateCTM(radians(90f));
                        break;

                    case MediaFileImageOrientation.LeftMirrored:
                        ctx.TranslateCTM(w, h);
                        ctx.RotateCTM(radians(270f));
                        ctx.ScaleCTM(1f, -1f);
                        break;

                    case MediaFileImageOrientation.Right:
                        ctx.TranslateCTM(0, h);
                        ctx.RotateCTM(radians(270f));
                        break;

                    case MediaFileImageOrientation.RightMirrored:
                        ctx.TranslateCTM(0, 0);
                        ctx.RotateCTM(radians(90f));
                        ctx.ScaleCTM(1f, -1f);
                        break;

                    default:
                        break;
                    }

                    ctx.DrawImage(new CoreGraphics.CGRect(0, 0, destW, destH), cg);

                    requestedImage = UIImage.FromImage(ctx.ToImage());

                    ctx.Dispose();
                }

                imageBytes = requestedImage.AsJPEG(options.Quality / 100f).ToArray();
                requestedImage.Dispose();
            });

            return(imageBytes);
        }