using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.IO; using System.Linq; using ImageMagick; using System.Threading.Tasks; using System.Drawing; namespace Kehyeedra3 { public static class Extensions { private static DateTime YeedraTime = new DateTime(2020, 2, 2, 0, 0, 0, DateTimeKind.Utc); public static ulong ToYeedraStamp(this DateTime time) => (ulong)(time.Subtract(YeedraTime)).TotalSeconds; public static DateTime FromYeedraStamp(this ulong time) => YeedraTime.AddSeconds(Convert.ToDouble(time)); public static string ToYeedraDisplay(this long number) { double numb = (double)number/10000; return numb.ToString("N4"); } public static double Remap(this int value, double min1, double max1, double min2, double max2) => ((double)value).Remap(min1, max1, min2, max2); public static double Remap(this ulong value, double min1, double max1, double min2, double max2) => ((double)value).Remap(min1, max1, min2, max2); public static double Remap(this double value, double min1, double max1, double min2, double max2) => min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); //https://stackoverflow.com/a/1262619 public static void Shuffle(this IList list) { using (RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider()) { int n = list.Count; while (n > 1) { byte[] box = new byte[1]; do provider.GetBytes(box); while (!(box[0] < n * (byte.MaxValue / n))); int k = (box[0] % n); n--; T value = list[k]; list[k] = list[n]; list[n] = value; } } } public static async Task GifPngMergeAsync(MagickImage pngFile, string gifFile, Rectangle rect, PixelInterpolateMethod interpolateMethod = PixelInterpolateMethod.Bilinear, bool trimEmpty = false) => await GifPngMergeAsync(pngFile, new FileStream(gifFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), rect, interpolateMethod, trimEmpty); public static async Task GifPngMergeAsync(Stream pngFile, string gifFile, Rectangle rect, PixelInterpolateMethod interpolateMethod = PixelInterpolateMethod.Bilinear, bool trimEmpty = false) => await GifPngMergeAsync(new MagickImage(pngFile), new FileStream(gifFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), rect, interpolateMethod, trimEmpty); public static async Task GifPngMergeAsync(string pngFile, Stream gifFile, Rectangle rect, PixelInterpolateMethod interpolateMethod = PixelInterpolateMethod.Bilinear, bool trimEmpty = false) => await GifPngMergeAsync(new MagickImage(pngFile), gifFile, rect, interpolateMethod, trimEmpty); public static async Task GifPngMergeAsync(string pngFile, string gifFile, Rectangle rect, PixelInterpolateMethod interpolateMethod = PixelInterpolateMethod.Bilinear, bool trimEmpty = false) => await GifPngMergeAsync(new MagickImage(pngFile), new FileStream(gifFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), rect, interpolateMethod, trimEmpty); public static async Task GifPngMergeAsync(MagickImage pngFile, Stream gifFile, Rectangle rect, PixelInterpolateMethod interpolateMethod = PixelInterpolateMethod.Bilinear, bool trimEmpty = false) { try { MagickImageCollection pngCollection = new MagickImageCollection(); using MagickImageCollection gifCollection = new MagickImageCollection(gifFile); int[] delay = new int[gifCollection.Count]; int indx = 0; foreach (var frame in gifCollection) { MagickImage pngTemplate = new MagickImage(pngFile); using MagickImage gifFrame = new MagickImage(frame); gifFrame.Alpha(AlphaOption.Set); if (trimEmpty) { gifFrame.BackgroundColor = MagickColors.None; gifFrame.ColorFuzz = new Percentage(1); gifFrame.Trim(); gifFrame.RePage(); } var size = GetSize(gifFrame, rect); gifFrame.InterpolativeResize(size.Width, size.Height, interpolateMethod); size.X = (rect.Width + rect.X) / 2 - (gifFrame.Width / 2); size.Y = (rect.Height + rect.Y) / 2 - (gifFrame.Height / 2); pngTemplate.Composite(gifFrame, size.X, size.Y, CompositeOperator.Over); pngCollection.Add(pngTemplate); delay[indx] = gifFrame.AnimationDelay; indx++; } pngCollection[0].AnimationDelay = 0; for (int index = 1; index < pngCollection.Count - 1; index++) { pngCollection[index].AnimationDelay = delay[index]; } if (pngCollection.Count > 1) { QuantizeSettings settings = new QuantizeSettings() { Colors = 2048 }; pngCollection.Quantize(settings); } return pngCollection; } catch (Exception ex) { Console.WriteLine($"Error processing; Exception = {ex}"); } return null; } static Rectangle GetSize(MagickImage img, Rectangle rect) { Rectangle output = new Rectangle(rect.X, rect.Y, 0, 0); double aspectRatio = (double)img.Width / img.Height; double otherAspect = (double)img.Height / img.Width; output.Width = (int)Math.Min(Math.Round(rect.Width - rect.X * aspectRatio), rect.Width - rect.X); output.Height = (int)(output.Width * otherAspect); return output; } } }