diff --git a/Pixiview/Illust/ViewIllustPage.xaml.cs b/Pixiview/Illust/ViewIllustPage.xaml.cs index 9875fb2..a74987b 100644 --- a/Pixiview/Illust/ViewIllustPage.xaml.cs +++ b/Pixiview/Illust/ViewIllustPage.xaml.cs @@ -614,7 +614,7 @@ namespace Pixiview.Illust } } - var success = await Task.Run(ugoira.ExportVideo); + var success = await Task.Run(ugoira.ExportVideo); // ugoira.ExportGif if (success != null) { var result = await FileStore.SaveVideoToGalleryAsync(success); diff --git a/Pixiview/Utils/Stores.cs b/Pixiview/Utils/Stores.cs index a3253e1..c33ea95 100644 --- a/Pixiview/Utils/Stores.cs +++ b/Pixiview/Utils/Stores.cs @@ -138,9 +138,9 @@ namespace Pixiview.Utils } } - public static string GetUgoiraVideoPath(string url) + public static string GetUgoiraPath(string url, string ext) { - return Path.Combine(PersonalFolder, ugoiraFolder, Path.GetFileNameWithoutExtension(url) + ".mp4"); + return Path.Combine(PersonalFolder, ugoiraFolder, Path.GetFileNameWithoutExtension(url) + ext); } private static T ReadObject(string file) diff --git a/Pixiview/Utils/Ugoira.cs b/Pixiview/Utils/Ugoira.cs index 969b913..b695f25 100644 --- a/Pixiview/Utils/Ugoira.cs +++ b/Pixiview/Utils/Ugoira.cs @@ -402,7 +402,7 @@ namespace Pixiview.Utils return null; } - var file = Stores.GetUgoiraVideoPath(ugoira.originalSrc); + var file = Stores.GetUgoiraPath(ugoira.originalSrc, ".mp4"); if (File.Exists(file)) { File.Delete(file); @@ -490,6 +490,51 @@ namespace Pixiview.Utils } return null; } + + public Task ExportGif() + { + if (ugoira == null || ugoira.frames.Any(f => f.Incompleted)) + { + return null; + } + + var file = Stores.GetUgoiraPath(ugoira.originalSrc, ".gif"); + if (File.Exists(file)) + { + File.Delete(file); + } + var fileURL = NSUrl.FromFilename(file); + + var dictFile = new NSMutableDictionary(); + var gifDictionaryFile = new NSMutableDictionary + { + { ImageIO.CGImageProperties.GIFLoopCount, NSNumber.FromFloat(0f) } + }; + dictFile.Add(ImageIO.CGImageProperties.GIFDictionary, gifDictionaryFile); + var dictFrame = new NSMutableDictionary(); + var gifDictionaryFrame = new NSMutableDictionary + { + { ImageIO.CGImageProperties.GIFDelayTime, NSNumber.FromFloat(ugoira.frames[0].delay / 1000f) } + }; + dictFrame.Add(ImageIO.CGImageProperties.GIFDictionary, gifDictionaryFrame); + + var task = new TaskCompletionSource(); + Xamarin.Essentials.MainThread.BeginInvokeOnMainThread(() => + { + var images = ugoira.frames.Select(f => UIImage.FromFile(f.FilePath)).ToArray(); + + var imageDestination = ImageIO.CGImageDestination.Create(fileURL, MobileCoreServices.UTType.GIF, images.Length); + imageDestination.SetProperties(dictFile); + for (int i = 0; i < images.Length; i++) + { + imageDestination.AddImage(images[i].CGImage, dictFrame); + } + imageDestination.Close(); + + task.SetResult(file); + }); + return task.Task; + } #endif }