| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 | 
							
- using System;
 
- using System.Drawing;
 
- using System.IO;
 
- using System.Threading.Tasks;
 
- using AVFoundation;
 
- using CoreGraphics;
 
- using CoreMedia;
 
- using Foundation;
 
- using UIKit;
 
- using Xamarin.Essentials;
 
- using MobileCoreServices;
 
- [assembly: Xamarin.Forms.Dependency(typeof(InABox.Mobile.iOS.ImageToolsiOS))]
 
- namespace InABox.Mobile.iOS
 
- {
 
-     
 
-     public class ImageToolsiOS : IImageTools
 
-     {
 
-         public byte[] CreateVideoThumbnail(byte[] video, int maxwidth, int 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 = ScaleImage(result, new Size(maxwidth, maxheight), 60);
 
-             
 
-             File.Delete(filename);
 
-             return result;
 
-         }
 
-         
 
-         public byte[] CreateThumbnail(byte[] source, int maxwidth, int maxheight)
 
-         {
 
-             return ScaleImage(source, new Size(maxwidth, maxheight), 60);
 
-         }
 
-         
 
-         public async Task<FileResult> PickPhotoAsync(int? compression, Size? constraints)
 
-         {
 
-             return await MainThread.InvokeOnMainThreadAsync(async () =>
 
-                 await InternalGetPhotoAsync<Permissions.Photos>(UIImagePickerControllerSourceType.PhotoLibrary, compression, constraints));
 
-         }
 
-         
 
-          public async Task<FileResult> CapturePhotoAsync(int? compression, Size? constraints)
 
-         {
 
-             return await MainThread.InvokeOnMainThreadAsync(async () =>
 
-                 await InternalGetPhotoAsync<Permissions.Camera>(UIImagePickerControllerSourceType.Camera, compression, constraints));
 
-         }
 
-         private async Task<FileResult> InternalGetPhotoAsync<TPermission>(UIImagePickerControllerSourceType source, int? compression, Size? constraints)
 
-             where TPermission : Permissions.BasePermission, new()
 
-         {
 
-             var taskCompletionSource = new TaskCompletionSource<FileResult>();
 
-             if (await Permissions.RequestAsync<TPermission>() == PermissionStatus.Granted)
 
-             {
 
-                 var imagePicker = new UIImagePickerController
 
-                 {
 
-                     SourceType = source,
 
-                     MediaTypes = new string[] { UTType.Image }
 
-                 };
 
-                 
 
-                 var viewController = Platform.GetCurrentUIViewController();
 
-                 imagePicker.AllowsEditing = false;
 
-                 imagePicker.FinishedPickingMedia += async (sender, e) =>
 
-                 {
 
-                     var jpegFilename = Path.Combine(FileSystem.CacheDirectory, $"{Guid.NewGuid()}.jpg");
 
-                     var source = e.Info[UIImagePickerController.OriginalImage] as UIImage;
 
-                     var rotated = AutoRotateImage(source);
 
-                     var scaled = ScaleImage(rotated, constraints);
 
-                     var result = scaled.AsJPEG(new nfloat(compression ?? 100)/100);
 
-                     await viewController.DismissViewControllerAsync(true);
 
-                     if (result.Save(jpegFilename, false, out var error))
 
-                     {
 
-                         taskCompletionSource.TrySetResult(new FileResult(jpegFilename));
 
-                     }
 
-                     else
 
-                     {
 
-                         taskCompletionSource.TrySetException(new Exception($"Error saving the image: {error}"));
 
-                     }
 
-                     imagePicker?.Dispose();
 
-                     imagePicker = null;
 
-                 };
 
-                 imagePicker.Canceled += async (sender, e) =>
 
-                 {
 
-                     await viewController.DismissViewControllerAsync(true);
 
-                     taskCompletionSource.TrySetResult(null);
 
-                     imagePicker?.Dispose();
 
-                     imagePicker = null;
 
-                 };
 
-                 await viewController.PresentViewControllerAsync(imagePicker, true);
 
-             }
 
-             else
 
-             {
 
-                 taskCompletionSource.TrySetResult(null);
 
-                 taskCompletionSource.TrySetException(new PermissionException("Camera permission not granted"));
 
-             }
 
-             return await taskCompletionSource.Task;
 
-         }
 
-         
 
-         private UIImage AutoRotateImage(UIImage source)
 
-         {
 
-             var rotation = source.Orientation switch
 
-             {
 
-                 UIImageOrientation.Right => 90F,
 
-                 UIImageOrientation.Up => 0F,
 
-                 UIImageOrientation.Left => -90F,
 
-                 UIImageOrientation.Down => 180F,
 
-                 _ => 0F
 
-             };
 
-             return RotateImage(source, rotation);
 
-         }
 
-         private UIImage RotateImage(UIImage source, float rotation)
 
-         {
 
-             UIImage imageToReturn = null;
 
-             float radians = -1 * ((float)(rotation * Math.PI) / 180);
 
-             bool isLandscape = false;
 
-             var x = source.Size.Width / 2;
 
-             var y = source.Size.Height / 2;
 
-             //https://stackoverflow.com/a/8536553
 
-             CGAffineTransform transform = new CGAffineTransform((nfloat)Math.Cos(radians), (nfloat)Math.Sin(radians), -(nfloat)Math.Sin(radians), (nfloat)Math.Cos(radians), (nfloat)(x - x * Math.Cos(radians)) + (nfloat)(y * Math.Sin(radians)), (nfloat)(y - x * Math.Sin(radians) - y * Math.Cos(radians)));
 
-             var diff = (source.Size.Height - source.Size.Width) / 2;
 
-             bool translateWidthAndHeight = false;
 
-             if (rotation == 90)
 
-             {
 
-                 translateWidthAndHeight = true;
 
-                 transform.Translate(diff, -diff);
 
-             }
 
-             else if (rotation == 180)
 
-             {
 
-                 //Transform.Translate(image.Size.Width, -image.Size.Height);
 
-             }
 
-             else if (rotation == 270)
 
-             {
 
-                 translateWidthAndHeight = true;
 
-                 transform.Translate(diff, -diff);
 
-             }
 
-             else if (rotation == 360)
 
-             {
 
-             }
 
-             if (translateWidthAndHeight)
 
-             {
 
-                 //now draw image
 
-                 using (var context = new CGBitmapContext(IntPtr.Zero,
 
-                                                         (int)source.Size.Height,
 
-                                                         (int)source.Size.Width,
 
-                                                         source.CGImage.BitsPerComponent,
 
-                                                         source.CGImage.BitsPerComponent * (int)source.Size.Width,
 
-                                                         source.CGImage.ColorSpace,
 
-                                                         source.CGImage.BitmapInfo))
 
-                 {
 
-                     context.ConcatCTM(transform);
 
-                     context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)source.Size.Width, (float)source.Size.Height)), source.CGImage);
 
-                     using (var imageRef = context.ToImage())
 
-                     {
 
-                         imageToReturn = new UIImage(imageRef);
 
-                     }
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 //now draw image
 
-                 using (var context = new CGBitmapContext(IntPtr.Zero,
 
-                                                         (int)source.Size.Width,
 
-                                                         (int)source.Size.Height,
 
-                                                         source.CGImage.BitsPerComponent,
 
-                                                         source.CGImage.BitsPerComponent * (int)source.Size.Height,
 
-                                                         source.CGImage.ColorSpace,
 
-                                                         source.CGImage.BitmapInfo))
 
-                 {
 
-                     context.ConcatCTM(transform);
 
-                     context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)source.Size.Width, (float)source.Size.Height)), source.CGImage);
 
-                     using (var imageRef = context.ToImage())
 
-                     {
 
-                         imageToReturn = new UIImage(imageRef);
 
-                     }
 
-                 }
 
-             }
 
-             return imageToReturn;
 
-         }
 
-         private UIImage ScaleImage(UIImage sourceImage, Size? constraints)
 
-         {
 
-             var maxwidth = constraints?.Width ?? sourceImage.Size.Width;
 
-             var maxheight = constraints?.Height ?? sourceImage.Size.Height;
 
-             var wRatio = maxwidth < sourceImage.Size.Width
 
-                 ? maxwidth / (double)sourceImage.Size.Width
 
-                 : 1.0F;
 
-             var hRatio = maxheight < sourceImage.Size.Height
 
-                 ? maxheight / (double)sourceImage.Size.Height
 
-                 : 1.0F;
 
-             var ratio = Math.Min(hRatio, wRatio);
 
-             if (ratio < 1.0F)
 
-             {
 
-                 var width = ratio * sourceImage.Size.Width;
 
-                 var height = ratio * sourceImage.Size.Height;
 
-                 UIGraphics.BeginImageContext(new CGSize(width, height));
 
-                 sourceImage.Draw(new CGRect(0, 0, width, height));
 
-                 var resultImage = UIGraphics.GetImageFromCurrentImageContext();
 
-                 UIGraphics.EndImageContext();
 
-                 return resultImage;
 
-             }
 
-             return sourceImage;
 
-         }
 
-         public byte[] RotateImage(byte[] source, float angle, int quality = 100)
 
-         {
 
-             byte[] result = { };
 
-             using (UIImage src = UIImage.LoadFromData(NSData.FromArray(source)))
 
-             {
 
-                 if (src != null)
 
-                 {
 
-                     var scaled = RotateImage(src, angle);
 
-                     using (NSData imageData = scaled.AsJPEG(new nfloat((float)quality / 100F)))
 
-                     {
 
-                         result = new byte[imageData.Length];
 
-                         System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, result, 0,
 
-                             Convert.ToInt32(imageData.Length));
 
-                     }
 
-                 }
 
-             }
 
-             return result;
 
-         }
 
-         public byte[] ScaleImage(byte[] source, Size? constraints, int quality = 100)
 
-         {
 
-             byte[] result = { };
 
-             using (UIImage src = UIImage.LoadFromData(NSData.FromArray(source)))
 
-             {
 
-                 if (src != null)
 
-                 {
 
-                     var scaled = ScaleImage(src, constraints);
 
-                     using (NSData imageData = scaled.AsJPEG(new nfloat((float)quality / 100F)))
 
-                     {
 
-                         result = new byte[imageData.Length];
 
-                         System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, result, 0,
 
-                             Convert.ToInt32(imageData.Length));
 
-                     }
 
-                 }
 
-             }
 
-             return result;
 
-         }
 
-     }
 
-     
 
- }
 
 
  |