using System; using System.IO; using AVFoundation; using CoreGraphics; using CoreMedia; using Foundation; using UIKit; [assembly: Xamarin.Forms.Dependency(typeof(InABox.Mobile.iOS.ImageToolsiOS))] namespace InABox.Mobile.iOS { public class ImageToolsiOS : IImageTools { public byte[] CreateVideoThumbnail(byte[] video, float maxwidth, float maxheight) { byte[] result = null; var filename = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), $"{Guid.NewGuid().ToString()}.tmp" ); File.WriteAllBytes(filename,video); // perhaps? on IOS, try to use - NSUrl.FromFilename (path) instead of - new Foundation.NSUrl(url) var asset = AVAsset.FromUrl(NSUrl.FromFilename(filename)); AVAssetImageGenerator imageGenerator = new AVAssetImageGenerator(asset); //AVAssetImageGenerator imageGenerator = new AVAssetImageGenerator(AVAsset.FromUrl((new Foundation.NSUrl(filename)))); imageGenerator.AppliesPreferredTrackTransform = true; CMTime actualTime; NSError error; CGImage cgImage = imageGenerator.CopyCGImageAtTime(new CMTime(1, 1), out actualTime, out error); using (var ms = new MemoryStream()) { var png = new UIImage(cgImage).AsPNG().AsStream(); png.CopyTo(ms); result = ms.ToArray(); } if (result != null) result = CreateThumbnail(result, maxwidth, maxheight); File.Delete(filename); return result; } public byte[] CreateThumbnail(byte[] source, float maxwidth, float maxheight) { byte[] result = { }; using (UIImage src = UIImage.LoadFromData(NSData.FromArray(source))) { if (src != null) { if ((src.Size.Width > 0.0F) && (src.Size.Height > 0.0F)) { var maxFactor = Math.Min(maxwidth / src.Size.Width, maxheight / src.Size.Height); var width = maxFactor * src.Size.Width; var height = maxFactor * src.Size.Height; UIGraphics.BeginImageContextWithOptions(new CGSize((float)width, (float)height), true, 1.0f); src.Draw(new CGRect(0, 0, (float)width, (float)height)); var tgt = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); using (NSData imageData = tgt.AsJPEG()) { result = new byte[imageData.Length]; System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, result, 0, Convert.ToInt32(imageData.Length)); } } } } return result; } } }