void UpdateStaticImage() { // Prepare the options to pass when fetching the (photo, or video preview) image. var options = new PHImageRequestOptions { DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, NetworkAccessAllowed = true, ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary info) => { stop = false; // Handler might not be called on the main queue, so re-dispatch for UI work. DispatchQueue.MainQueue.DispatchSync(() => { ProgressView.Progress = (float)progress; }); } }; PHImageManager.DefaultManager.RequestImageForAsset(Asset, TargetSize, PHImageContentMode.AspectFit, options, (image, info) => { // Hide the progress view now the request has completed. ProgressView.Hidden = true; // If successful, show the image view and display the image. if (image == null) { return; } // Now that we have the image, show it. #if __IOS__ && !__TVOS__ LivePhotoView.Hidden = true; #endif ImageView.Hidden = false; ImageView.Image = image; }); }
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) { var cell = collectionView.DequeueReusableCell(AlbumCollectionViewCell.ReuseIdentifier, indexPath) as AlbumCollectionViewCell; if (cell == null) { throw new InvalidProgramException("Unable to dequeue an AlbumCollectionViewCell"); } var collection = albums [indexPath.Row]; cell.ImageView.Image = null; cell.Label.Text = collection.LocalizedTitle; var firstAsset = (PHAsset)PHAsset.FetchAssets(collection, new PHFetchOptions()).firstObject; if (firstAsset != null) { var options = new PHImageRequestOptions { Synchronous = true }; PHImageManager.DefaultManager.RequestImageForAsset(firstAsset, cell.Bounds.Size, PHImageContentMode.AspectFit, options, (requestedImage, _) => { cell.ImageView.Image = requestedImage; }); } return(cell); }
void PickerController_FinishedPickingAssets(object sender, MultiAssetEventArgs args) { List <object> encodedImages = new List <object>(); foreach (var asset in args.Assets) { PHImageManager imageManager = new PHImageManager(); // we make sure the image are saved in the same quality with this option PHImageRequestOptions options = new PHImageRequestOptions { NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, Synchronous = true }; imageManager.RequestImageForAsset(asset, new CGSize(asset.PixelWidth, asset.PixelHeight), PHImageContentMode.Default, options, (image, info) => { byte[] dataBytes = new byte[image.AsPNG().Length]; System.Runtime.InteropServices.Marshal.Copy(image.AsPNG().Bytes, dataBytes, 0, Convert.ToInt32(image.AsPNG().Length)); encodedImages.Add(dataBytes); }); } // post the message with the list attached MessagingCenter.Send <object, object>(this, MessagingKeys.DidFinishSelectingImages, encodedImages); }
public async Task <ObservableCollection <Photo> > Get(int start, int count, Quality quality = Quality.Low) { if (results == null) { var succeded = await Import(); if (!succeded) { return(new ObservableCollection <Photo>()); } } var photos = new ObservableCollection <Photo>(); var options = new PHImageRequestOptions() { NetworkAccessAllowed = true, DeliveryMode = quality == Quality.Low ? PHImageRequestOptionsDeliveryMode.FastFormat : PHImageRequestOptionsDeliveryMode.HighQualityFormat }; Index startIndex = start; Index endIndex = start + count; if (endIndex.Value >= results.Length) { endIndex = results.Length - 1; } if (startIndex.Value > endIndex.Value) { return(new ObservableCollection <Photo>()); } foreach (PHAsset asset in results[startIndex.Value..endIndex])
private void LastTakenPhotoFunction() { if (!UIImagePickerController.IsSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)) { alertView = new UIAlertView("SnagR Upload Photos APP", "Sorry, you cannot select pictures with your device", new UIAlertViewDelegate(), "OK"); alertView.Show(); return; } //imagePicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary; //ALAssetsLibrary library = new ALAssetsLibrary(); PHFetchOptions fetchOptions = new PHFetchOptions(); fetchOptions.SortDescriptors = new NSSortDescriptor[] { new NSSortDescriptor("creationDate", false) }; PHFetchResult fetchResult = PHAsset.FetchAssets(PHAssetMediaType.Image, fetchOptions); PHAsset lastAsset = (Photos.PHAsset)fetchResult.LastObject; PHImageRequestOptions option = new PHImageRequestOptions(); option.ResizeMode = PHImageRequestOptionsResizeMode.Exact; PHImageManager.DefaultManager.RequestImageData(lastAsset, option, (data, dataUti, orientation, info) => nsSelectedImage = data); //PHImageManager.DefaultManager.RequestImageForAsset(lastAsset, new CGSize(100, 100), PHImageContentMode.AspectFill, options:option,(UIImage result, NSDictionary info) => {selectedImage = result}); selectedImage = UIImage.LoadFromData(nsSelectedImage); TestImagePlace.Image = selectedImage; //imagePicker.AssetsLibrary UploadProcess(); }
private void Handle_PickedImages(object sender, MultiAssetEventArgs e) { ImageEntries = new List <ImageEntry>(); var phAssetArray = e.Assets; var manager = PHImageManager.DefaultManager; using (var options = new PHImageRequestOptions { Synchronous = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, ResizeMode = PHImageRequestOptionsResizeMode.Exact }) { foreach (var asset in phAssetArray) { if (asset.MediaType == PHAssetMediaType.Video) { HandleVideoSelected(); return; } manager.RequestImageForAsset(asset, new CGSize(asset.PixelWidth, asset.PixelHeight), PHImageContentMode.Default, options, (result, info) => { var resources = PHAssetResource.GetAssetResources(asset); var name = resources != null && resources.Length > 0 ? resources[0].OriginalFilename : string.Empty; ImageEntries.Add(new ImageEntry(result.ToSKImage(), name, (DateTime)asset.CreationDate, null)); }); } LaunchAnalysisScreen(ImageEntries); } }
void UpdateStaticImage() { // Prepare the options to pass when fetching the live photo. var options = new PHImageRequestOptions { DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, NetworkAccessAllowed = true }; options.ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary info) => { stop = false; DispatchQueue.MainQueue.DispatchAsync(() => { ProgressView.Progress = (float)progress; }); }; PHImageManager.DefaultManager.RequestImageForAsset(Asset, TargetSize, PHImageContentMode.AspectFit, options, (result, info) => { // Hide the progress view now the request has completed. ProgressView.Hidden = true; // Check if the request was successful. if (result == null) { return; } // Show the UIImageView and use it to display the requested image. ShowStaticPhotoView(); ImageView.Image = result; }); }
public ImageService() { this.imagesResult = new List <NSObject>(); this.imageManager = PHImageManager.DefaultManager; this.requestOptions = new PHImageRequestOptions() { Synchronous = true }; }
// On load, construct the CIRawFilter public override void ViewDidLoad () { base.ViewDidLoad (); var asset = Asset; if (asset == null) return; // Setup options to request original image. var options = new PHImageRequestOptions { Version = PHImageRequestOptionsVersion.Original, Synchronous = true }; // Request the image data and UTI type for the image. PHImageManager.DefaultManager.RequestImageData (asset, options, (imageData, dataUTI, _, __) => { if (imageData == null || dataUTI == null) return; // Create a CIRawFilter from original image data. // UTI type is passed in to provide the CIRawFilter with a hint about the UTI type of the Raw file. //var rawOptions = [String (kCGImageSourceTypeIdentifierHint) : dataUTI ] var rawOptions = new NSMutableDictionary (); var imageIOLibrary = Dlfcn.dlopen ("/System/Library/Frameworks/ImageIO.framework/ImageIO", 0); var key = Dlfcn.GetIntPtr (imageIOLibrary, "kCGImageSourceTypeIdentifierHint"); rawOptions.LowlevelSetObject (dataUTI, key); ciRawFilter = CIFilter.CreateRawFilter (imageData, rawOptions); if (ciRawFilter == null) return; // Get the native size of the image produced by the CIRawFilter. var sizeValue = ciRawFilter.ValueForKey (Keys.kCIOutputNativeSizeKey) as CIVector; if (sizeValue != null) imageNativeSize = new CGSize (sizeValue.X, sizeValue.Y); // Record the original value of the temperature, and setup the editing slider. var tempValue = (NSNumber)ciRawFilter.ValueForKey (Keys.kCIInputNeutralTemperatureKey); if (tempValue != null) { originalTemp = tempValue.FloatValue; TempSlider.SetValue (tempValue.FloatValue, animated: false); } // Record the original value of the tint, and setup the editing slider. var tintValue = (NSNumber)ciRawFilter.ValueForKey (Keys.kCIInputNeutralTintKey); if (tintValue != null) { originalTint = tintValue.FloatValue; TintSlider.SetValue (tintValue.FloatValue, animated: false); } }); // Create EAGL context used to render the CIImage produced by the CIRawFilter to display. ImageView.Context = new EAGLContext (EAGLRenderingAPI.OpenGLES3); ciContext = CIContext.FromContext (ImageView.Context, new CIContextOptions { CIImageFormat = CIImage.FormatRGBAh }); }
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; } }
public async Task <GalleryImageXF> IF_SyncPhotoFromCloud(IGalleryPickerResultListener galleryPickerResultListener, GalleryImageXF imageSet, SyncPhotoOptions options) { try { bool FinishSync = false; Debug.WriteLine(imageSet.OriginalPath); var sortOptions = new PHFetchOptions(); sortOptions.SortDescriptors = new NSSortDescriptor[] { new NSSortDescriptor("creationDate", false) }; var FeechPhotoByIdentifiers = PHAsset.FetchAssetsUsingLocalIdentifiers( new string[] { imageSet.OriginalPath }, sortOptions).Cast <PHAsset>().FirstOrDefault(); if (FeechPhotoByIdentifiers != null) { var requestOptions = new PHImageRequestOptions() { NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, ResizeMode = PHImageRequestOptionsResizeMode.None, }; var requestSize = new CoreGraphics.CGSize(options.Width, options.Height); requestSize = PHImageManager.MaximumSize; PHImageManager.DefaultManager.RequestImageForAsset(FeechPhotoByIdentifiers, requestSize, PHImageContentMode.AspectFit, requestOptions, (result, info) => { if (result != null) { var newImage = result.ResizeImage(options); imageSet.ImageRawData = newImage.AsJPEG(options.Quality).ToArray(); } FinishSync = true; }); do { if (FinishSync) { return(imageSet); } await Task.Delay(1000); } while (!FinishSync); } return(imageSet); } catch (Exception ex) { Debug.WriteLine(ex.StackTrace); return(imageSet); } }
public void IF_GetImageSourceFilePath(ImageSource imageSource, string filePath) { var options = new PHImageRequestOptions { Synchronous = true }; var pHAsset = JsonConvert.DeserializeObject <PHAsset>(filePath); PHImageManager.DefaultManager.RequestImageForAsset(pHAsset, new CoreGraphics.CGSize(100, 100), PHImageContentMode.AspectFit, options, (result, info) => { imageSource = ImageSource.FromStream(() => result.AsJPEG(0.7f).AsStream()); }); }
/// <summary> /// /// </summary> /// <param name="url"></param> /// <returns></returns> public static NSDictionary GetPhotoLibraryMetadata(NSUrl url) { NSDictionary meta = null; var image = PHAsset.FetchAssets(new NSUrl[] { url }, new PHFetchOptions()).firstObject as PHAsset; if (image == null) { return(null); } try { var imageManager = PHImageManager.DefaultManager; var requestOptions = new PHImageRequestOptions { Synchronous = true, NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, }; imageManager.RequestImageData(image, requestOptions, (data, dataUti, orientation, info) => { try { var fullimage = CIImage.FromData(data); if (fullimage?.Properties != null) { meta = new NSMutableDictionary { [ImageIO.CGImageProperties.Orientation] = NSNumber.FromNInt((int)(fullimage.Properties.Orientation ?? CIImageOrientation.TopLeft)), [ImageIO.CGImageProperties.ExifDictionary] = fullimage.Properties.Exif?.Dictionary ?? new NSDictionary(), [ImageIO.CGImageProperties.TIFFDictionary] = fullimage.Properties.Tiff?.Dictionary ?? new NSDictionary(), [ImageIO.CGImageProperties.GPSDictionary] = fullimage.Properties.Gps?.Dictionary ?? new NSDictionary(), [ImageIO.CGImageProperties.IPTCDictionary] = fullimage.Properties.Iptc?.Dictionary ?? new NSDictionary(), [ImageIO.CGImageProperties.JFIFDictionary] = fullimage.Properties.Jfif?.Dictionary ?? new NSDictionary() }; } } catch (Exception ex) { Console.WriteLine(ex); } }); } catch { } return(meta); }
public async Task <IEnumerable <XMediaFile> > GetMediaFiles() { var images = new List <XMediaFile>(); var permission = await PHPhotoLibrary.RequestAuthorizationAsync(); if (permission == PHAuthorizationStatus.Authorized) { PHImageManager imageManager = PHImageManager.DefaultManager; var requestOptions = new PHImageRequestOptions() { Synchronous = true }; var results = PrepareResults(); for (int i = 0; i < results.Count; i++) { var asset = results.ObjectAt(i) as PHAsset; imageManager.RequestImageForAsset(asset, new CGSize(100, 100), PHImageContentMode.AspectFill, requestOptions, (image, info) => { var funcBytes = new Func <byte[]>(() => { byte[] rawBytes = null; using (NSData imageData = image.AsJPEG()) { rawBytes = new Byte[imageData.Length]; System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, rawBytes, 0, (int)imageData.Length); } return(rawBytes); }); images.Add(new XMediaFile() { Data = funcBytes, DateAdded = asset.CreationDate.ToDateTime().ToShortDate(), MediaType = asset.MediaType.ToString() }); }); } return(images); } return(images); }
private void CellAction(ActionType type, Tuple <NSIndexPath, PHAsset> photo) { if (type == ActionType.Close) { ShowAlert(Core.Localization.LocalizationKeys.PickedPhotosLimit); return; } NavigationItem.RightBarButtonItem.Enabled = false; pickedPhoto = photo; previousPhotoLocalIdentifier = source.CurrentlySelectedItem?.Item2?.LocalIdentifier; var pickOptions = new PHImageRequestOptions() { ResizeMode = PHImageRequestOptionsResizeMode.Exact, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat }; var imageSize = ImageHelper.CalculateInSampleSize(new CGSize(photo.Item2.PixelWidth, photo.Item2.PixelHeight), Core.Constants.PhotoMaxSize, Core.Constants.PhotoMaxSize); _m.RequestImageForAsset(photo.Item2, imageSize, PHImageContentMode.Default, pickOptions, PickImage); }
private void ChangeImage(PHAsset asset, PHImageManager imageManager, PHImageRequestOptions options) { var assetSize = new CGSize(asset.PixelWidth, asset.PixelHeight); DispatchQueue.DefaultGlobalQueue.DispatchAsync(() => imageManager?.RequestImageForAsset(asset, assetSize, PHImageContentMode.AspectFill, options, (result, info) => DispatchQueue.MainQueue.DispatchAsync(() => { CurrentMediaType = MediaType.Image; _albumView.ImageCropView.Hidden = false; _albumView.MovieView.Hidden = true; _albumView.ImageCropView.ImageSize = assetSize; _albumView.ImageCropView.Image = result; }))); }
private void HandleImage(IEnumerable <PHObject> images) { foreach (PHAsset image in images) { if (image.MediaType == PHAssetMediaType.Image) { PHImageRequestOptions options = new PHImageRequestOptions() { NetworkAccessAllowed = false, ResizeMode = PHImageRequestOptionsResizeMode.Exact, Version = PHImageRequestOptionsVersion.Original }; PHImageManager.DefaultManager.RequestImageData(image, options, async(d, t, o, i) => { string path = ((NSUrl)i["PHImageFileURLKey"])?.Path; string mimeType = UTType.GetPreferredTag(t, UTType.TagClassMIMEType); await _probe.CreateAndStoreDatumAsync(path, mimeType, (DateTime)image.CreationDate); }); } else if (image.MediaType == PHAssetMediaType.Video) { PHVideoRequestOptions options = new PHVideoRequestOptions() { NetworkAccessAllowed = false, Version = PHVideoRequestOptionsVersion.Original }; PHImageManager.DefaultManager.RequestAvAsset(image, options, async(a, _, i) => { if (a is AVUrlAsset urlAsset) { string path = urlAsset.Url.Path; string extension = urlAsset.Url.PathExtension; string uniformTypeIdentifier = UTType.CreatePreferredIdentifier(UTType.TagClassFilenameExtension, extension, null); string mimeType = UTType.GetPreferredTag(uniformTypeIdentifier, UTType.TagClassMIMEType); await _probe.CreateAndStoreDatumAsync(path, mimeType, (DateTime)image.CreationDate); } }); } } }
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) { var cell = collectionView.DequeueReusableCell (LightboxCollectionViewCell.ReuseIdentifier, indexPath) as LightboxCollectionViewCell; if (cell == null) throw new InvalidProgramException ("Unable to dequeue a LightboxCollectionViewCell"); cell.ImageView.Image = null; var options = new PHImageRequestOptions { Synchronous = true }; var asset = assets [indexPath.Row]; PHImageManager.DefaultManager.RequestImageForAsset (asset, cell.Bounds.Size, PHImageContentMode.AspectFit, options, (requestedImage, _) => { cell.ImageView.Image = requestedImage; }); return cell; }
public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration) { if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad) { return; } var layout = CollectionViewFlowLayoutForOrientation(toInterfaceOrientation, _picker); //Update the AssetGridThumbnailSize: var scale = UIScreen.MainScreen.Scale; AssetGridThumbnailSize = new CGSize(layout.ItemSize.Width * scale, layout.ItemSize.Height * scale); ResetCachedAssets(); var options = new PHImageRequestOptions { Synchronous = false, NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.Opportunistic, ResizeMode = PHImageRequestOptionsResizeMode.Fast }; //This is optional. Reload visible thumbnails: foreach (var cell in CollectionView.VisibleCells) { var typedCell = (GMGridViewCell)cell; var currentTag = cell.Tag; _imageManager.RequestImageForAsset(typedCell.Asset, AssetGridThumbnailSize, PHImageContentMode.AspectFill, options, (image, info) => { // Only update the thumbnail if the cell tag hasn't changed. Otherwise, the cell has been re-used. if (cell.Tag == currentTag && typedCell.ImageView != null && image != null) { typedCell.ImageView.Image = image; } }); } CollectionView.SetCollectionViewLayout(layout, true); }
public string GetFileDescription(string file) { if (string.IsNullOrEmpty(file)) { return(null); } long fileSize = 0; var asset = PHAsset.FetchAssets(new[] { new NSUrl(file) }, null).LastObject as PHAsset; if (asset != null) { var options = new PHImageRequestOptions { Synchronous = true }; PHImageManager.DefaultManager.RequestImageData(asset, options, (data, dataUti, orientation, info) => { fileSize = Convert.ToInt64(data.Length); }); } return(NSByteCountFormatter.Format(fileSize, NSByteCountFormatterCountStyle.Binary)); }
public Tuple <byte[], string, string> ReadFile(string file) { Tuple <byte[], string, string> result = null; var asset = PHAsset.FetchAssets(new[] { new NSUrl(file) }, null).LastObject as PHAsset; if (asset != null) { var options = new PHImageRequestOptions { Synchronous = true }; PHImageManager.DefaultManager.RequestImageData(asset, options, (data, dataUti, orientation, info) => { var extension = new NSUrl(dataUti).PathExtension; var uti = UTType.CreatePreferredIdentifier(UTType.TagClassFilenameExtension, extension, null); var mime = UTType.GetPreferredTag(uti, UTType.TagClassMIMEType); var dataBytes = new byte[data.Length]; Marshal.Copy(data.Bytes, dataBytes, 0, Convert.ToInt32(data.Length)); result = new Tuple <byte[], string, string>(dataBytes, dataUti, mime); }); } return(result); }
public void GetImage(PHAsset asset, CGSize size, PHImageRequestOptions options, Action<UIImage> action) { try { PHImageManager.DefaultManager.RequestImageForAsset(asset, size, PHImageContentMode.AspectFit, options, (image, info) => { try { action(image); } catch (Exception ex) { Console.WriteLine(ex); } }); } catch (Exception ex) { Console.WriteLine(ex); } }
public void BindDataToCell(GalleryNative galleryDirectory, Action action) { var count = galleryDirectory.Images.Count; txtTitle.Text = galleryDirectory.Collection.LocalizedTitle; txtDescription.Text = "(" + count + ")"; imageView.ClipsToBounds = true; imageView.ContentMode = UIViewContentMode.ScaleAspectFill; try { var sortOptions = new PHFetchOptions(); sortOptions.SortDescriptors = new NSSortDescriptor[] { new NSSortDescriptor("creationDate", false) }; var items = PHAsset.FetchAssets(galleryDirectory.Collection, sortOptions).Cast <PHAsset>().ToList(); var options = new PHImageRequestOptions { Synchronous = true }; PHImageManager.DefaultManager.RequestImageForAsset(items[0], imageView.Bounds.Size, PHImageContentMode.AspectFit, options, (requestedImage, _) => { imageView.Image = requestedImage; }); } catch (Exception ex) { Console.WriteLine(ex.StackTrace); } if (ActionClick == null) { ActionClick = action; bttClick.TouchUpInside += (sender, e) => { ActionClick(); }; } }
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) { var cell = collectionView.DequeueReusableCell(LightboxCollectionViewCell.ReuseIdentifier, indexPath) as LightboxCollectionViewCell; if (cell == null) { throw new InvalidProgramException("Unable to dequeue a LightboxCollectionViewCell"); } cell.ImageView.Image = null; var options = new PHImageRequestOptions { Synchronous = true }; var asset = assets [indexPath.Row]; PHImageManager.DefaultManager.RequestImageForAsset(asset, cell.Bounds.Size, PHImageContentMode.AspectFit, options, (requestedImage, _) => { cell.ImageView.Image = requestedImage; }); return(cell); }
public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath) { var cell = collectionView.DequeueReusableCell (AlbumCollectionViewCell.ReuseIdentifier, indexPath) as AlbumCollectionViewCell; if (cell == null) throw new InvalidProgramException ("Unable to dequeue an AlbumCollectionViewCell"); var collection = albums [indexPath.Row]; cell.ImageView.Image = null; cell.Label.Text = collection.LocalizedTitle; var firstAsset = (PHAsset)PHAsset.FetchAssets (collection, new PHFetchOptions ()).firstObject; if (firstAsset != null) { var options = new PHImageRequestOptions { Synchronous = true }; PHImageManager.DefaultManager.RequestImageForAsset (firstAsset, cell.Bounds.Size, PHImageContentMode.AspectFit, options, (requestedImage, _) => { cell.ImageView.Image = requestedImage; }); } return cell; }
private static string StorePickedImage(PHAsset asset, int quality, float scale, bool rotate, MediaFile tempMedia) { var tcs = new TaskCompletionSource <string>(); var task = tcs.Task; var imageManager = PHImageManager.DefaultManager; using (var requestOptions = new PHImageRequestOptions { Synchronous = true, NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, }) { imageManager.RequestImageData(asset, requestOptions, (data, dataUti, orientation, info) => { Task.Factory.StartNew(() => { StoreImageData(asset, quality, scale, rotate, tempMedia, info, data, tcs); }); }); } return(task.Result); }
void UpdateStaticImage () { // Prepare the options to pass when fetching the (photo, or video preview) image. var options = new PHImageRequestOptions { DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, NetworkAccessAllowed = true, ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary info) => { stop = false; // Handler might not be called on the main queue, so re-dispatch for UI work. DispatchQueue.MainQueue.DispatchSync (() => { ProgressView.Progress = (float)progress; }); } }; PHImageManager.DefaultManager.RequestImageForAsset (Asset, TargetSize, PHImageContentMode.AspectFit, options, (image, info) => { // Hide the progress view now the request has completed. ProgressView.Hidden = true; // If successful, show the image view and display the image. if (image == null) return; // Now that we have the image, show it. #if __IOS__ && !__TVOS__ LivePhotoView.Hidden = true; #endif ImageView.Hidden = false; ImageView.Image = image; }); }
async void FinishedPickingAssets(object sender, MultiAssetEventArgs args) { var picker = (GMImagePickerController)sender; picker.FinishedPickingAssets -= FinishedPickingAssets; picker.Canceled -= OnPickerCanceled; // synchronous: NO.异步。 // a.deliveryMode: Opportunistic: 会返回多张图片 // 1). ResizeMode.None: 先返回低清的缩略图,再返回原图大小 // 2). ResizeMode.Fast: 先返回低清的缩略图,再返回的原图会使用targetSize来最优解码图片,获得的图片大小可能比targetSize大 // 3). ResizeMode.Exact: 先返回低清的缩略图,再返回的原图会使用targetSize的高质量图 // b.deliveryMode: HighQualityFormat: 只会返回一张高清图片 // 1). ResizeMode.None: 返回的是原图大小 // 2). ResizeMode.Fast: 当原图是压缩图时,会使用targetSize来最优解码图片,获得的图片大小可能比targetSize大 // 3). ResizeMode.Exact: 解压和Fast一样,但是返回的是指定targetSize的高质量图 // c.deliveryMode: FastFormat: 只会返回一张图片,并且可能是低清图 // 1). ResizeMode.None: 返回一张低清图 // 2). ResizeMode.Fast: 返回一张低清图 // 3). ResizeMode.Exact: 返回一张低清图 var options = new PHImageRequestOptions { NetworkAccessAllowed = true, Synchronous = false, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, ResizeMode = PHImageRequestOptionsResizeMode.Exact, }; var tcs = new TaskCompletionSource <object>(); bool completed = false; List <FileData> result = new List <FileData>(); for (var i = 0; i < args.Assets.Length; i++) { var asset = args.Assets[i]; switch (asset.MediaType) { case PHAssetMediaType.Video: // 未测 PHImageManager.DefaultManager.RequestImageForAsset( asset, new SizeF(FileData.ThumbSize, FileData.ThumbSize), PHImageContentMode.AspectFit, options, async(img, info) => { // 获取路径,麻烦 TaskCompletionSource <NSUrl> tcsUrl = new TaskCompletionSource <NSUrl>(); var vOptions = new PHVideoRequestOptions { NetworkAccessAllowed = true, Version = PHVideoRequestOptionsVersion.Original, DeliveryMode = PHVideoRequestOptionsDeliveryMode.FastFormat, }; PHImageManager.DefaultManager.RequestAvAsset( asset, vOptions, (avAsset, audioMix, vInfo) => { if (avAsset is AVUrlAsset avUrl) { tcsUrl.TrySetResult(avUrl.Url); } else { tcsUrl.TrySetResult(null); } }); NSUrl url = await tcsUrl.Task; // 生成文件描述和缩略图 var fd = ParseUrl(url); fd.Desc = $"{asset.PixelWidth} x {asset.PixelHeight} ({fd.Ext.TrimStart('.')})"; fd.ThumbPath = Path.Combine(Kit.CachePath, Kit.NewGuid + "-t.jpg"); img.AsJPEG().Save(fd.ThumbPath, true); result.Add(fd); if (args.Assets.Length == result.Count && !completed) { completed = true; tcs.TrySetResult(null); } }); break; default: PHImageManager.DefaultManager.RequestImageForAsset( asset, new SizeF(FileData.ThumbSize, FileData.ThumbSize), PHImageContentMode.AspectFit, options, async(img, info) => { // 获取路径,麻烦 TaskCompletionSource <NSUrl> tcsUrl = new TaskCompletionSource <NSUrl>(); asset.RequestContentEditingInput(new PHContentEditingInputRequestOptions(), (input, _) => { tcsUrl.TrySetResult(input.FullSizeImageUrl); }); NSUrl url = await tcsUrl.Task; // 生成文件描述和缩略图 var fd = ParseUrl(url); fd.Desc = $"{asset.PixelWidth} x {asset.PixelHeight} ({fd.Ext.TrimStart('.')})"; if (asset.PixelWidth > FileData.ThumbSize || asset.PixelHeight > FileData.ThumbSize) { fd.ThumbPath = Path.Combine(Kit.CachePath, Kit.NewGuid + "-t.jpg"); img.AsJPEG().Save(fd.ThumbPath, true); } result.Add(fd); if (args.Assets.Length == result.Count && !completed) { completed = true; tcs.TrySetResult(null); } }); break; } } // 用临时tcs等待比直接在回调方法中用_tcs速度大幅提高!!! await tcs.Task; _tcs.TrySetResult(result); }
private UIImage GetImage(PHAsset asset) { UIImage result = null; var options = new PHImageRequestOptions { Synchronous = true, }; var size = new CGSize(asset.PixelWidth, asset.PixelHeight); PHImageManager.DefaultManager.RequestImageForAsset(asset, size, PHImageContentMode.AspectFit, options, (image, info) => result = image); return result; }
/* * Task<ObservableCollection<Photo>> IPhotoImporter.Get(int startIndex, int count, Quality quality = Quality.Low) * { * throw new NotImplementedException(); * } * * Task<ObservableCollection<Photo>> IPhotoImporter.Get(List<string> filenames, Quality quality = Quality.Low) * { * throw new NotImplementedException(); * } */ private void RequestImage(ObservableCollection <Photo> photos, PHAsset asset, string filename, PHImageRequestOptions options) { PHImageManager.DefaultManager.RequestImageForAsset(asset, PHImageManager.MaximumSize, PHImageContentMode.AspectFill, options, (image, info) => { //Original code uses image.AsPNG() using (NSData imageData = image.AsJPEG()) { var bytes = new byte[imageData.Length]; System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length)); var photo = new Photo() { Bytes = bytes, Filename = filename }; photos.Add(photo); } }); }
public void ShowImagePicker(bool needsHighQuality) { //Create the image gallery picker. var picker = new GMImagePickerController { Title = "Select Photo", CustomDoneButtonTitle = "Finished", CustomCancelButtonTitle = "Cancel", ColsInPortrait = 4, ColsInLandscape = 7, MinimumInteritemSpacing = 2.0f, DisplaySelectionInfoToolbar = true, AllowsMultipleSelection = true, ShowCameraButton = true, AutoSelectCameraImages = true, ModalPresentationStyle = UIModalPresentationStyle.Popover, MediaTypes = new[] { PHAssetMediaType.Image }, CustomSmartCollections = new[] { PHAssetCollectionSubtype.SmartAlbumUserLibrary, PHAssetCollectionSubtype.AlbumRegular }, NavigationBarTextColor = Color.White.ToUIColor(), NavigationBarBarTintColor = Color.FromHex("#c5dd36").ToUIColor(), PickerTextColor = Color.Black.ToUIColor(), ToolbarTextColor = Color.FromHex("#c5dd36").ToUIColor(), NavigationBarTintColor = Color.White.ToUIColor() }; //Set a limit on the number of photos the user can select. I use 12 selected photos beause of memory limitations on iOS. picker.ShouldSelectAsset += (sender, args) => args.Cancel = picker.SelectedAssets.Count > 11; // select image handler GMImagePickerController.MultiAssetEventHandler[] handler = { null }; //cancel handler EventHandler[] cancelHandler = { null }; //define the handler handler[0] = (sender, args) => { var tcs = Interlocked.Exchange(ref _completionSource, null); picker.FinishedPickingAssets -= handler[0]; picker.Canceled -= cancelHandler[0]; System.Diagnostics.Debug.WriteLine("User finished picking assets. {0} items selected.", args.Assets.Length); var imageManager = new PHImageManager(); var RequestImageOption = new PHImageRequestOptions(); if (needsHighQuality) { RequestImageOption.DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat; } else { RequestImageOption.DeliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat; } RequestImageOption.ResizeMode = PHImageRequestOptionsResizeMode.Fast; RequestImageOption.NetworkAccessAllowed = true; RequestImageOption.Synchronous = false; _preselectedAssets = args.Assets; if (!_preselectedAssets.Any()) { //no image selected tcs.TrySetResult(null); } else { var images = new List <string>(); var documentsDirectory = Environment.GetFolderPath (Environment.SpecialFolder.Personal); int cnt = 1; foreach (var asset in _preselectedAssets) { DispatchQueue.MainQueue.DispatchAsync(() => { //For each image, create a file path for it. imageManager.RequestImageForAsset(asset, PHImageManager.MaximumSize, PHImageContentMode.Default, RequestImageOption, (image, info) => { using (NSAutoreleasePool autoreleasePool = new NSAutoreleasePool()) { System.Diagnostics.Debug.WriteLine("Total memory being used: {0}", GC.GetTotalMemory(false)); var filename = Guid.NewGuid().ToString(); System.Diagnostics.Debug.WriteLine("filename: " + filename); string filepath = Save(image, filename.ToString(), documentsDirectory); System.Diagnostics.Debug.WriteLine("filepath: " + filepath); images.Add(filepath); //When we are on the last image, send the images to the carousel view. if (cnt == args.Assets.Length) { Device.BeginInvokeOnMainThread(() => { MessagingCenter.Send <App, List <string> >((App)Xamarin.Forms.Application.Current, "ImagesSelectediOS", images); }); } cnt++; //Dispose of objects and call the garbage collector. asset.Dispose(); autoreleasePool.Dispose(); GC.Collect(); } }); }); } tcs.TrySetResult(images); } }; picker.FinishedPickingAssets += handler[0]; cancelHandler[0] = (sender, args) => { var tcs = Interlocked.Exchange(ref _completionSource, null); picker.FinishedPickingAssets -= handler[0]; picker.Canceled -= cancelHandler[0]; tcs.TrySetResult(null); }; picker.Canceled += cancelHandler[0]; //show picker picker.PresentUsingRootViewController(); }
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) { var cell = (GMAlbumsViewCell)tableView.DequeueReusableCell(CellReuseIdentifier); if (cell == null) { cell = new GMAlbumsViewCell(UITableViewCellStyle.Subtitle, CellReuseIdentifier); cell.Accessory = UITableViewCellAccessory.DisclosureIndicator; } // Increment the cell's tag var currentTag = cell.Tag + 1; cell.Tag = currentTag; // Set the label cell.TextLabel.Font = UIFont.FromName(_parent._picker.PickerFontName, _parent._picker.PickerFontHeaderSize); cell.TextLabel.Text = _parent._collectionsFetchResultsTitles [indexPath.Section][indexPath.Row]; cell.TextLabel.TextColor = _parent._picker.PickerTextColor; // Retrieve the pre-fetched assets for this album: var assetsFetchResult = _parent._collectionsFetchResultsAssets[indexPath.Section][indexPath.Row]; // Display the number of assets if (_parent._picker.DisplayAlbumsNumberOfAssets) { cell.DetailTextLabel.Font = UIFont.FromName(_parent._picker.PickerFontName, _parent._picker.PickerFontNormalSize); // Just use the number of assets. Album app does this: cell.DetailTextLabel.Text = string.Format("{0:0}", assetsFetchResult.Count); cell.DetailTextLabel.TextColor = _parent._picker.PickerTextColor; } var numberOfAssets = assetsFetchResult.Count; // Set the 3 images (if exists): if (numberOfAssets > 0) { var scale = UIScreen.MainScreen.Scale; var options = new PHImageRequestOptions { Synchronous = false, NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.Opportunistic, ResizeMode = PHImageRequestOptionsResizeMode.Fast }; // Compute the thumbnail pixel size: var tableCellThumbnailSize1 = new CGSize(AlbumThumbnailSize1.Width * scale, AlbumThumbnailSize1.Height * scale); var asset = (PHAsset)assetsFetchResult[_parent._picker.GridSortOrder == SortOrder.Ascending ? numberOfAssets - 1 : 0]; cell.SetVideoLayout(asset.MediaType == PHAssetMediaType.Video); _parent._imageManager.RequestImageForAsset(asset, tableCellThumbnailSize1, PHImageContentMode.AspectFill, options, (image, info) => { if (cell.Tag == currentTag && cell.ImageView1 != null && image != null) { cell.ImageView1.Image = image; } }); // Second & third images: // TODO: Only preload the 3pixels height visible frame! if (numberOfAssets > 1) { // Compute the thumbnail pixel size: var tableCellThumbnailSize2 = new CGSize(AlbumThumbnailSize2.Width * scale, AlbumThumbnailSize2.Height * 2); asset = (PHAsset)assetsFetchResult [_parent._picker.GridSortOrder == SortOrder.Ascending ? numberOfAssets - 2 : 1]; _parent._imageManager.RequestImageForAsset(asset, tableCellThumbnailSize2, PHImageContentMode.AspectFill, options, (image, info) => { if (cell.Tag == currentTag && cell.ImageView2 != null && image != null) { cell.ImageView2.Image = image; } }); } else { cell.ImageView2.Image = null; } if (numberOfAssets > 2) { // Compute the thumbnail pixel size: var tableCellThumbnailSize3 = new CGSize(AlbumThumbnailSize3.Width * scale, AlbumThumbnailSize3.Height * 2); asset = (PHAsset)assetsFetchResult [_parent._picker.GridSortOrder == SortOrder.Ascending ? numberOfAssets - 3 : 2]; _parent._imageManager.RequestImageForAsset(asset, tableCellThumbnailSize3, PHImageContentMode.AspectFill, options, (image, info) => { if (cell.Tag == currentTag && cell.ImageView3 != null && image != null) { cell.ImageView3.Image = image; } }); } else { cell.ImageView3.Image = null; } } else { cell.SetVideoLayout(false); var emptyFolder = UIImage.FromFile("GMEmptyFolder"); cell.ImageView3.Image = emptyFolder; cell.ImageView2.Image = emptyFolder; cell.ImageView1.Image = emptyFolder; } return(cell); }
public Task <SupportImageXF> IF_SyncPhotoFromCloud(SupportImageXF imageSet, SyncPhotoOptions options) { ManualResetEvent manualResetEvent = new ManualResetEvent(false); return(Task.Factory.StartNew(() => { try { manualResetEvent.Reset(); var sortOptions = new PHFetchOptions(); sortOptions.SortDescriptors = new NSSortDescriptor[] { new NSSortDescriptor("creationDate", false) }; var FeechPhotoByIdentifiers = PHAsset.FetchAssetsUsingLocalIdentifiers( new string[] { imageSet.OriginalPath }, sortOptions).Cast <PHAsset>().FirstOrDefault(); Console.WriteLine(imageSet.OriginalPath + " ==> Run at step 1"); if (FeechPhotoByIdentifiers != null) { var requestOptions = new PHImageRequestOptions() { NetworkAccessAllowed = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, ResizeMode = PHImageRequestOptionsResizeMode.None, }; var requestSize = PHImageManager.MaximumSize; Console.WriteLine(imageSet.OriginalPath + " ==> Run at step 2"); PHImageManager.DefaultManager.RequestImageForAsset(FeechPhotoByIdentifiers, requestSize, PHImageContentMode.AspectFit, requestOptions, (image, info) => { Console.WriteLine(imageSet.OriginalPath + " ==> Run at step 3"); if (image != null) { //var newImage = result.ResizeImage(options); //imageSet.ImageRawData = newImage.AsJPEG(options.Quality).ToArray(); try { var url = info.ObjectForKey(new NSString("PHImageFileURLKey")) as NSUrl; if (url == null) { // Get image and save to file var filePath = Path.Combine(Path.GetTempPath(), $"Photo_{Path.GetTempFileName()}"); image.AsJPEG().Save(filePath, false, out _); url = new NSUrl(filePath); } var fileName = url.Path; var newWidth = image.Size.Width; var newHeight = image.Size.Height; // Create temp file path var fileNameOnly = Path.GetFileNameWithoutExtension(fileName); var fileExtension = Path.GetExtension(fileName); var newFileName = fileNameOnly + "_" + DateTime.Now.ToFormatString("yyyyMMddHHmmss") + "_" + newWidth + "x" + newHeight + fileExtension; var tempPath = Path.Combine(Path.GetTempPath(), newFileName); FileHelper.CreateFile(tempPath); // Write data to temp file using (var newStream = FileHelper.GetWriteFileStream(tempPath)) { using (var imageData = image.AsJPEG()) { var buffer = new byte[imageData.Length]; System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, buffer, 0, Convert.ToInt32(imageData.Length)); newStream.Write(buffer, 0, buffer.Length); imageSet.ProcessFilePath = tempPath; //Console.WriteLine("Finish item at ==> " + tempPath); } } Console.WriteLine(imageSet.OriginalPath + " ==> Run at step 4"); manualResetEvent.Set(); } catch (Exception ex) { // Ignore Console.WriteLine("Error for " + imageSet.OriginalPath); Console.WriteLine(ex.StackTrace); manualResetEvent.Set(); } } else { Console.WriteLine("Can not sync image"); manualResetEvent.Set(); } }); } else { Console.WriteLine(imageSet.OriginalPath + " ==> Run at step 5"); manualResetEvent.Set(); } manualResetEvent.WaitOne(); return imageSet; } catch (Exception ex) { Console.WriteLine(ex); return imageSet; } })); }
private static UIImage GetImage(PHAsset asset) { UIImage result = null; var options = new PHImageRequestOptions { Synchronous = true, NetworkAccessAllowed = true }; nfloat scale = UIScreen.MainScreen.Scale; var size = new CGSize(UIScreen.MainScreen.Bounds.Size.Width * scale, UIScreen.MainScreen.Bounds.Size.Height * scale); ImageCache.Instance.GetImage(asset, size, options, x => result = x); return result; }
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; }; if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0)) { manager.RequestImageDataAndOrientation(ph, phOptions, (data, i, orientation, k) => { if (data != null) { image = new UIImage(data, 1.0f); } }); } else { 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)); }
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 void StartCachingImagePreview() { try { var options = new PHImageRequestOptions { Synchronous = false, NetworkAccessAllowed = true }; var imageSize = new CGSize(16, 160); _cachingImageManager.StartCaching(_assets.Values.ToArray(), imageSize, PHImageContentMode.AspectFit, options); } catch (Exception ex) { Console.WriteLine(ex); } }
private void UpdateImage(PHAsset asset) { var options = new PHImageRequestOptions { Synchronous = true, }; var size = new CGSize(asset.PixelWidth, asset.PixelHeight); PHImageManager.DefaultManager.RequestImageForAsset(asset, size, PHImageContentMode.AspectFit, options, (image, info) => ReplaseImage(image)); }
void UpdateStaticImage () { // Prepare the options to pass when fetching the live photo. var options = new PHImageRequestOptions { DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, NetworkAccessAllowed = true }; options.ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary info) => { stop = false; DispatchQueue.MainQueue.DispatchAsync (() => { ProgressView.Progress = (float)progress; }); }; PHImageManager.DefaultManager.RequestImageForAsset (Asset, TargetSize, PHImageContentMode.AspectFit, options, (result, info) => { // Hide the progress view now the request has completed. ProgressView.Hidden = true; // Check if the request was successful. if (result == null) return; // Show the UIImageView and use it to display the requested image. ShowStaticPhotoView (); ImageView.Image = result; }); }
void UpdateToolbars() { // Enable editing buttons if the asset can be edited. EditButton.Enabled = Asset.CanPerformEditOperation(PHAssetEditOperation.Content); FavoriteButton.Enabled = Asset.CanPerformEditOperation(PHAssetEditOperation.Properties); FavoriteButton.Title = Asset.Favorite ? "♥︎" : "♡"; // Enable the trash button if the asset can be deleted. if (AssetCollection != null) { TrashButton.Enabled = AssetCollection.CanPerformEditOperation(PHCollectionEditOperation.RemoveContent); } else { TrashButton.Enabled = Asset.CanPerformEditOperation(PHAssetEditOperation.Delete); } // Set the appropriate toolbarItems based on the mediaType of the asset. if (Asset.MediaType == PHAssetMediaType.Video) { #if __TVOS__ NavigationItem.LeftBarButtonItems = new UIBarButtonItem[] { PlayButton, FavoriteButton, TrashButton }; #elif __IOS__ ToolbarItems = new UIBarButtonItem[] { FavoriteButton, Space, PlayButton, Space, TrashButton }; if (NavigationController != null) { NavigationController.ToolbarHidden = false; } #endif } else { #if __TVOS__ // In tvOS, PHLivePhotoView doesn't do playback gestures, // so add a play button for Live Photos. if (Asset.PlaybackStyle == PHAssetPlaybackStyle.LivePhoto) { NavigationItem.LeftBarButtonItems = new UIBarButtonItem[] { LivePhotoPlayButton, FavoriteButton, TrashButton } } ; else { NavigationItem.LeftBarButtonItems = new UIBarButtonItem[] { FavoriteButton, TrashButton } }; #elif __IOS__ // In iOS, present both stills and Live Photos the same way, because // PHLivePhotoView provides the same gesture-based UI as in Photos app. ToolbarItems = new UIBarButtonItem[] { FavoriteButton, Space, TrashButton }; if (NavigationController != null) { NavigationController.ToolbarHidden = false; } #endif } } void UpdateStillImage() { // Prepare the options to pass when fetching the (photo, or video preview) image. var options = new PHImageRequestOptions { DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, NetworkAccessAllowed = true, ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary info) => { stop = false; // Handler might not be called on the main queue, so re-dispatch for UI work. DispatchQueue.MainQueue.DispatchSync(() => { ProgressView.Progress = (float)progress; }); } }; ProgressView.Hidden = false; PHImageManager.DefaultManager.RequestImageForAsset(Asset, GetTargetSize(), PHImageContentMode.AspectFit, options, (image, info) => { // Hide the progress view now the request has completed. ProgressView.Hidden = true; // If successful, show the image view and display the image. if (image == null) { return; } // Now that we have the image, show it. ImageView.Hidden = false; ImageView.Image = image; }); } void UpdateLivePhoto() { // Prepare the options to pass when fetching the live photo. var options = new PHLivePhotoRequestOptions { DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, NetworkAccessAllowed = true, ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary dictionary) => { stop = false; // Handler might not be called on the main queue, so re-dispatch for UI work. DispatchQueue.MainQueue.DispatchSync(() => ProgressView.Progress = (float)progress); } }; ProgressView.Hidden = false; // Request the live photo for the asset from the default PHImageManager. PHImageManager.DefaultManager.RequestLivePhoto(Asset, GetTargetSize(), PHImageContentMode.AspectFit, options, (livePhoto, info) => { // Hide the progress view now the request has completed. ProgressView.Hidden = true; // If successful, show the live photo view and display the live photo. if (livePhoto == null) { return; } // Now that we have the Live Photo, show it. ImageView.Hidden = true; AnimatedImageView.Hidden = true; LivePhotoView.Hidden = false; LivePhotoView.LivePhoto = livePhoto; // Playback a short section of the live photo; similar to the Photos share sheet. if (!isPlayingHint) { isPlayingHint = true; LivePhotoView.StartPlayback(PHLivePhotoViewPlaybackStyle.Hint); } }); } void UpdateAnimatedImage() { // Prepare the options to pass when fetching the (photo, or video preview) image. var options = new PHImageRequestOptions { DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, Version = PHImageRequestOptionsVersion.Original, NetworkAccessAllowed = true, ProgressHandler = (double progress, NSError error, out bool stop, NSDictionary info) => { stop = false; // Handler might not be called on the main queue, so re-dispatch for UI work. DispatchQueue.MainQueue.DispatchSync(() => { ProgressView.Progress = (float)progress; }); } }; ProgressView.Hidden = false; PHImageManager.DefaultManager.RequestImageData(Asset, options, (data, dataUti, orientation, info) => { // Hide the progress view now the request has completed. ProgressView.Hidden = true; // If successful, show the image view and display the image. if (data == null) { return; } var animatedImage = new AnimatedImage(data); LivePhotoView.Hidden = true; ImageView.Hidden = true; AnimatedImageView.Hidden = false; AnimatedImageView.AnimatedImage = animatedImage; AnimatedImageView.IsPlaying = true; }); } #endregion #region Asset editing void RevertAsset(UIAlertAction action) { PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(() => { var request = PHAssetChangeRequest.ChangeRequest(Asset); request.RevertAssetContentToOriginal(); }, (success, error) => { if (!success) { Console.WriteLine($"can't revert asset: {error.LocalizedDescription}"); } }); } void ApplyFilter(CIFilter filter) { // Set up a handler to make sure we can handle prior edits. var options = new PHContentEditingInputRequestOptions(); options.CanHandleAdjustmentData = (adjustmentData => { return(adjustmentData.FormatIdentifier == formatIdentifier && adjustmentData.FormatVersion == formatVersion); }); // Prepare for editing. Asset.RequestContentEditingInput(options, (input, requestStatusInfo) => { if (input == null) { throw new InvalidProgramException($"can't get content editing input: {requestStatusInfo}"); } // This handler gets called on the main thread; dispatch to a background queue for processing. DispatchQueue.GetGlobalQueue(DispatchQueuePriority.Default).DispatchAsync(() => { // Create a PHAdjustmentData object that describes the filter that was applied. var adjustmentData = new PHAdjustmentData( formatIdentifier, formatVersion, NSData.FromString(filter.Name, NSStringEncoding.UTF8)); // NOTE: // This app's filter UI is fire-and-forget. That is, the user picks a filter, // and the app applies it and outputs the saved asset immediately. There's // no UI state for having chosen but not yet committed an edit. This means // there's no role for reading adjustment data -- you do that to resume // in-progress edits, and this sample app has no notion of "in-progress". // // However, it's still good to write adjustment data so that potential future // versions of the app (or other apps that understand our adjustement data // format) could make use of it. // Create content editing output, write the adjustment data. var output = new PHContentEditingOutput(input) { AdjustmentData = adjustmentData }; // Select a filtering function for the asset's media type. Action <CIFilter, PHContentEditingInput, PHContentEditingOutput, Action> applyFunc; if (Asset.MediaSubtypes.HasFlag(PHAssetMediaSubtype.PhotoLive)) { applyFunc = ApplyLivePhotoFilter; } else if (Asset.MediaType == PHAssetMediaType.Image) { applyFunc = ApplyPhotoFilter; } else { applyFunc = ApplyVideoFilter; } // Apply the filter. applyFunc(filter, input, output, () => { // When rendering is done, commit the edit to the Photos library. PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(() => { var request = PHAssetChangeRequest.ChangeRequest(Asset); request.ContentEditingOutput = output; }, (success, error) => { if (!success) { Console.WriteLine($"can't edit asset: {error.LocalizedDescription}"); } }); }); }); }); } void ApplyPhotoFilter(CIFilter filter, PHContentEditingInput input, PHContentEditingOutput output, Action completion) { // Load the full size image. var inputImage = new CIImage(input.FullSizeImageUrl); if (inputImage == null) { throw new InvalidProgramException("can't load input image to edit"); } // Apply the filter. filter.Image = inputImage.CreateWithOrientation(input.FullSizeImageOrientation); var outputImage = filter.OutputImage; // Write the edited image as a JPEG. // TODO: https://bugzilla.xamarin.com/show_bug.cgi?id=44503 NSError error; if (!ciContext.WriteJpegRepresentation(outputImage, output.RenderedContentUrl, inputImage.ColorSpace, new NSDictionary(), out error)) { throw new InvalidProgramException($"can't apply filter to image: {error.LocalizedDescription}"); } completion(); } void ApplyLivePhotoFilter(CIFilter filter, PHContentEditingInput input, PHContentEditingOutput output, Action completion) { // This app filters assets only for output. In an app that previews // filters while editing, create a livePhotoContext early and reuse it // to render both for previewing and for final output. var livePhotoContext = new PHLivePhotoEditingContext(input); livePhotoContext.FrameProcessor2 = (IPHLivePhotoFrame frame, ref NSError _) => { filter.Image = frame.Image; return(filter.OutputImage); }; livePhotoContext.SaveLivePhoto(output, (PHLivePhotoEditingOption)null, (success, error) => { if (success) { completion(); } else { Console.WriteLine("can't output live photo"); } }); // Applying edits to a Live Photo currently crashes // TODO: https://bugzilla.xamarin.com/show_bug.cgi?id=58227 } void ApplyVideoFilter(CIFilter filter, PHContentEditingInput input, PHContentEditingOutput output, Action completion) { // Load AVAsset to process from input. var avAsset = input.AudiovisualAsset; if (avAsset == null) { throw new InvalidProgramException("can't get AV asset to edit"); } // Set up a video composition to apply the filter. var composition = AVVideoComposition.CreateVideoComposition(avAsset, request => { filter.Image = request.SourceImage; var filtered = filter.OutputImage; request.Finish(filtered, null); }); // Export the video composition to the output URL. var export = new AVAssetExportSession(avAsset, AVAssetExportSessionPreset.HighestQuality) { OutputFileType = AVFileType.QuickTimeMovie, OutputUrl = output.RenderedContentUrl, VideoComposition = composition }; export.ExportAsynchronously(completion); }
private Task<List<UIImage>> GetSharedImages() { List<PHAsset> assets = _selectedImages.Values.Select(x => _imageCache.GetAsset(x.LocalIdentifier)).ToList(); var images = new List<UIImage>(); var options = new PHImageRequestOptions { Synchronous = true, DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat, NetworkAccessAllowed = true }; return Task.Run(() => { foreach (PHAsset asset in assets) { var size = new CGSize(asset.PixelWidth, asset.PixelHeight); _imageCache.GetImage(asset, size, options, x => images.Add(x)); } return images; }); }