You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
6.3 KiB
150 lines
6.3 KiB
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<T>(this IList<T> 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<MagickImageCollection> 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<MagickImageCollection> 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<MagickImageCollection> 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<MagickImageCollection> 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<MagickImageCollection> 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;
|
|
}
|
|
}
|
|
} |