private void UpdateCachedAssets () { var isViewVisible = IsViewLoaded && View.Window != null; if (!isViewVisible) { return; } // The preheat window is twice the height of the visible rect var preheatRect = CollectionView.Bounds; preheatRect = preheatRect.Inset (0.0f, -0.5f * preheatRect.Height); // If scrolled by a "reasonable" amount... var delta = Math.Abs(preheatRect.GetMidY() - _previousPreheatRect.GetMidY()); if (delta > CollectionView.Bounds.Height / 3.0f) { // Compute the assets to start caching and to stop caching. var addedIndexPaths = new List<NSIndexPath> (); var removedIndexPaths = new List<NSIndexPath> (); ComputeDifferenceBetweenRect (_previousPreheatRect, preheatRect, (removedRect) => { removedIndexPaths.AddRange(GetIndexPathsForElementsInRect(removedRect)); }, (addedRect) => { addedIndexPaths.AddRange(GetIndexPathsForElementsInRect(addedRect)); }); var assetsToStartCaching = GetAssetsAtIndexPaths (addedIndexPaths); var assetsToStopCaching = GetAssetsAtIndexPaths (removedIndexPaths); var options = new PHImageRequestOptions { Synchronous = false, NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.Opportunistic, ResizeMode = PHImageRequestOptionsResizeMode.Fast }; if (assetsToStartCaching != null) { _imageManager.StartCaching (assetsToStartCaching, AssetGridThumbnailSize, PHImageContentMode.AspectFill, options); } if (assetsToStopCaching != null) { _imageManager.StopCaching (assetsToStopCaching, AssetGridThumbnailSize, PHImageContentMode.AspectFill, options); } _previousPreheatRect = preheatRect; } }
void UpdateCachedAssets() { bool isViewVisible = IsViewLoaded && View.Window != null; if (!isViewVisible) { return; } // The preheat window is twice the height of the visible rect. CGRect preheatRect = CollectionView.Bounds; preheatRect = preheatRect.Inset(0f, -.5f * preheatRect.Height); nfloat delta = NMath.Abs(preheatRect.GetMidY() - previousPreheatRect.GetMidY()); if (delta > CollectionView.Bounds.Height / 3.0f) { // Compute the assets to start caching and to stop caching. var addedIndexPaths = new List <NSIndexPath> (); var removedIndexPaths = new List <NSIndexPath> (); ComputeDifferenceBetweenRect(previousPreheatRect, preheatRect, removedRect => { var indexPaths = CollectionView.GetIndexPaths(removedRect); if (indexPaths != null) { removedIndexPaths.AddRange(indexPaths); } }, addedRect => { var indexPaths = CollectionView.GetIndexPaths(addedRect); if (indexPaths != null) { addedIndexPaths.AddRange(indexPaths); } }); var assetsToStartCaching = AssetsAtIndexPaths(addedIndexPaths.ToArray()); var assetsToStopCaching = AssetsAtIndexPaths(removedIndexPaths.ToArray()); // Update the assets the PHCachingImageManager is caching. if (assetsToStartCaching != null) { imageManager.StartCaching(assetsToStartCaching, assetGridThumbnailSize, PHImageContentMode.AspectFill, null); } if (assetsToStopCaching != null) { imageManager.StopCaching(assetsToStopCaching, assetGridThumbnailSize, PHImageContentMode.AspectFill, null); } // Store the preheat rect to compare against in the future. previousPreheatRect = preheatRect; } }
void UpdateCachedAssets() { bool isViewVisible = IsViewLoaded && View.Window != null; if (!isViewVisible) { return; } // The preheat window is twice the height of the visible rect. CGRect preheatRect = CollectionView.Bounds; preheatRect = preheatRect.Inset(0, -preheatRect.Height / 2); // Update only if the visible area is significantly different from the last preheated area. nfloat delta = NMath.Abs(preheatRect.GetMidY() - previousPreheatRect.GetMidY()); if (delta <= CollectionView.Bounds.Height / 3) { return; } // Compute the assets to start caching and to stop caching. var rects = ComputeDifferenceBetweenRect(previousPreheatRect, preheatRect); var addedAssets = rects.Added .SelectMany(rect => CollectionView.GetIndexPaths(rect)) .Select(indexPath => FetchResult.ObjectAt(indexPath.Item)) .Cast <PHAsset> () .ToArray(); var removedAssets = rects.Removed .SelectMany(rect => CollectionView.GetIndexPaths(rect)) .Select(indexPath => FetchResult.ObjectAt(indexPath.Item)) .Cast <PHAsset> () .ToArray(); // Update the assets the PHCachingImageManager is caching. imageManager.StartCaching(addedAssets, thumbnailSize, PHImageContentMode.AspectFill, null); imageManager.StopCaching(removedAssets, thumbnailSize, PHImageContentMode.AspectFill, null); // Store the preheat rect to compare against in the future. previousPreheatRect = preheatRect; }
/// <summary> /// Update cached assets to fit the preheated rect /// </summary> public void UpdateCachedAssets() { var collectionView = _albumView.CollectionView; var preheatRect = CGRect.Inflate(collectionView.Bounds, 0.0f, 0.5f * collectionView.Bounds.Height); var delta = Math.Abs(preheatRect.GetMidY() - _previousPreheatRect.GetMidY()); if (delta > collectionView.Bounds.Height / 3.0) { var rects = ComputeDifferenceBetweenRect(_previousPreheatRect, preheatRect); var addedIndexPaths = GetIndexPathsForRects(collectionView, rects.Item1); var removedIndexPaths = GetIndexPathsForRects(collectionView, rects.Item2); var assetsToStartCaching = AssetsAtIndexPaths(addedIndexPaths); var assetsToStopCaching = AssetsAtIndexPaths(removedIndexPaths); _imageManager?.StartCaching(assetsToStartCaching, _cellSize, PHImageContentMode.AspectFill, null); _imageManager?.StopCaching(assetsToStopCaching, _cellSize, PHImageContentMode.AspectFill, null); _previousPreheatRect = preheatRect; } }
async Task <IList <MediaAsset> > LoadMediaAsync() { IList <MediaAsset> assets = new List <MediaAsset>(); var imageManager = new PHCachingImageManager(); var hasPermission = await RequestPermissionAsync(); if (hasPermission) { await Task.Run(async() => { var thumbnailRequestOptions = new PHImageRequestOptions(); thumbnailRequestOptions.ResizeMode = PHImageRequestOptionsResizeMode.Fast; thumbnailRequestOptions.DeliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat; thumbnailRequestOptions.NetworkAccessAllowed = true; thumbnailRequestOptions.Synchronous = true; var requestOptions = new PHImageRequestOptions(); requestOptions.ResizeMode = PHImageRequestOptionsResizeMode.Exact; requestOptions.DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat; requestOptions.NetworkAccessAllowed = true; requestOptions.Synchronous = true; var fetchOptions = new PHFetchOptions(); fetchOptions.SortDescriptors = new NSSortDescriptor[] { new NSSortDescriptor("creationDate", false) }; fetchOptions.Predicate = NSPredicate.FromFormat($"mediaType == {(int)PHAssetMediaType.Image} || mediaType == {(int)PHAssetMediaType.Video}"); var fetchResults = PHAsset.FetchAssets(fetchOptions); var tmpPath = Path.GetTempPath(); var allAssets = fetchResults.Select(p => p as PHAsset).ToArray(); var thumbnailSize = new CGSize(300.0f, 300.0f); imageManager.StartCaching(allAssets, thumbnailSize, PHImageContentMode.AspectFit, thumbnailRequestOptions); imageManager.StartCaching(allAssets, PHImageManager.MaximumSize, PHImageContentMode.AspectFit, requestOptions); foreach (var result in fetchResults) { var phAsset = (result as PHAsset); var name = PHAssetResource.GetAssetResources(phAsset)?.FirstOrDefault()?.OriginalFilename; var asset = new MediaAsset() { Id = phAsset.LocalIdentifier, Name = name, Type = phAsset.MediaType == PHAssetMediaType.Image ? MediaAssetType.Image : MediaAssetType.Video, }; imageManager.RequestImageForAsset(phAsset, thumbnailSize, PHImageContentMode.AspectFit, thumbnailRequestOptions, (image, info) => { if (image != null) { NSData imageData = null; if (image.CGImage.RenderingIntent == CGColorRenderingIntent.Default) { imageData = image.AsJPEG(0.8f); } else { imageData = image.AsPNG(); } if (imageData != null) { var fileName = Path.Combine(tmpPath, $"tmp_thumbnail_{Path.GetFileNameWithoutExtension(name)}.jpg"); NSError error = null; imageData.Save(fileName, true, out error); if (error == null) { asset.PreviewPath = fileName; } } } }); switch (phAsset.MediaType) { case PHAssetMediaType.Image: imageManager.RequestImageForAsset(phAsset, PHImageManager.MaximumSize, PHImageContentMode.AspectFit, requestOptions, (image, info) => { if (image != null) { NSData imageData = null; if (image.CGImage.RenderingIntent == CGColorRenderingIntent.Default) { imageData = image.AsJPEG(0.8f); } else { imageData = image.AsPNG(); } if (imageData != null) { var fileName = Path.Combine(tmpPath, $"tmp_{name}"); NSError error = null; imageData.Save(fileName, true, out error); if (error == null) { asset.Path = fileName; } } } }); break; case PHAssetMediaType.Video: var videoRequestOptions = new PHVideoRequestOptions(); videoRequestOptions.NetworkAccessAllowed = true; var tcs = new TaskCompletionSource <bool>(); imageManager.RequestAvAsset(phAsset, null, (vAsset, audioMix, info) => { var avAsset = vAsset as AVUrlAsset; var avData = NSData.FromUrl(avAsset.Url); NSError error = null; var path = Path.Combine(tmpPath, $"tmp_{name}"); avData.Save(path, true, out error); if (error == null) { asset.Path = path; tcs.TrySetResult(true); } else { tcs.TrySetResult(false); } }); await tcs.Task; break; } UIApplication.SharedApplication.InvokeOnMainThread(delegate { OnMediaAssetLoaded?.Invoke(this, new MediaEventArgs(asset)); }); assets.Add(asset); if (requestStop) { break; } } }); imageManager.StopCaching(); } return(assets); }
public Task <IEnumerable <MediaAsset> > Query(MediaTypes mediaTypes, DateTimeOffset date) { var tcs = new TaskCompletionSource <IEnumerable <MediaAsset> >(); Task.Run(() => { var filter = "creationDate >= %@ && " + GetFilter(mediaTypes); var fetchOptions = new PHFetchOptions { IncludeHiddenAssets = false, IncludeAllBurstAssets = false, Predicate = NSPredicate.FromFormat(filter, (NSDate)date.LocalDateTime), SortDescriptors = new [] { new NSSortDescriptor("creationDate", false) } }; var fetchAssets = PHAsset .FetchAssets(fetchOptions) .OfType <PHAsset>() .ToArray(); var options = new PHAssetResourceRequestOptions { NetworkAccessAllowed = false }; var imageCache = new PHCachingImageManager(); imageCache.StartCaching( fetchAssets, PHImageManager.MaximumSize, PHImageContentMode.Default, new PHImageRequestOptions { NetworkAccessAllowed = false } ); var assets = new List <MediaAsset>(fetchAssets.Count()); foreach (var asset in fetchAssets) { //result.MediaType //result.Hidden //result.Duration //result.LocalIdentifier //result.Location; //result.ModificationDate //result.PixelHeight; //result.PixelWidth; //result.CreationDate switch (asset.MediaType) { case PHAssetMediaType.Image: imageCache.RequestImageData( asset, new PHImageRequestOptions { }, (data, fn, orientation, dict) => { } ); break; case PHAssetMediaType.Video: imageCache.RequestAvAsset( asset, new PHVideoRequestOptions { NetworkAccessAllowed = false, DeliveryMode = PHVideoRequestOptionsDeliveryMode.HighQualityFormat }, (ass, mix, dict) => { } ); break; case PHAssetMediaType.Audio: break; } } imageCache.StopCaching(); tcs.SetResult(assets); }); return(tcs.Task); }