public static async Task CreateMazeAnimationGifAsync(HashSet <MazeTransformationStep> mazeTransformationSteps, IMaze maze, string label, int tilesize) { if (maze == null) { throw new ArgumentNullException(nameof(maze)); } int stepsPerImage = 30; int index = 0; using (var gif = new AnimatedGifCreator($"{label}.gif", 16)) // 16ms == 60fps { await gif.AddFrameAsync(GetMazeImage(maze, tilesize), delay : -1, quality : GifQuality.Bit8).ConfigureAwait(false); foreach (MazeTransformationStep step in mazeTransformationSteps) { maze.TransformMaze(step); index++; if (index % stepsPerImage == 0) { await gif.AddFrameAsync(GetMazeImage(maze, tilesize), delay : -1, quality : GifQuality.Bit8).ConfigureAwait(false); } } var finished = GetMazeImage(maze, tilesize); for (int i = 40 - 1; i >= 0; i--) { await gif.AddFrameAsync(finished, delay : -1, quality : GifQuality.Bit8).ConfigureAwait(false); } } }
private static async Task <MemoryStream> ToStream(this Bitmap[] frames) { var ms = new MemoryStream(); using (var gif = new AnimatedGifCreator(ms)) { foreach (var image in frames) { await gif.AddFrameAsync(image); } } ms.Position = 0; return(ms); }
public async Task HeadpatCommand([Optional] IGuildUser User) { if (User == null) { User = Context.Guild.GetUser(Context.User.Id); } string NameOfUser = Regex.Replace(User.Username, "[^a-zA-Z]", "", RegexOptions.Compiled); if (NameOfUser.Length < 2) { NameOfUser = "******"; } string ImageCacheDir = Path.Combine(Directory.GetCurrentDirectory(), "ImageCache"); if (!Directory.Exists(ImageCacheDir)) { Directory.CreateDirectory(ImageCacheDir); } string FilePath = Path.Join(ImageCacheDir, $"{NameOfUser}.gif"); using (AnimatedGifCreator Gif = AnimatedGif.AnimatedGif.Create(FilePath, 80)) { string[] Files = Directory.GetFiles(FunConfiguration.HeadpatsDir, "*.png", SearchOption.AllDirectories); using WebClient WebClient = new(); using MemoryStream MemoryStream = new(WebClient.DownloadData(User.GetTrueAvatarUrl())); using Image PFPImage = Image.FromStream(MemoryStream); for (int Index = 0; Index < Files.Length; Index++) { using Image Headpat = Image.FromFile(Files[Index]); using Bitmap DrawnImage = new(Headpat.Width, Headpat.Height); List <ushort> HeadpatPos = FunConfiguration.HeadpatPositions[Index]; using (Graphics Graphics = Graphics.FromImage(DrawnImage)) { Graphics.DrawImage(PFPImage, HeadpatPos[0], HeadpatPos[1], HeadpatPos[2], HeadpatPos[3]); Graphics.DrawImage(Headpat, 0, 0); } await Gif.AddFrameAsync(DrawnImage, delay : -1, quality : GifQuality.Bit8); } } using (Discord.Image EmoteImage = new (FilePath)) { IGuild Guild = DiscordSocketClient.GetGuild(FunConfiguration.HeadpatStorageGuild); Console.WriteLine(NameOfUser.Length); Console.WriteLine(EmoteImage); GuildEmote PrevEmote = Guild.Emotes.Where(Emote => Emote.Name == NameOfUser).FirstOrDefault(); if (PrevEmote != null) { await Guild.DeleteEmoteAsync(PrevEmote); } GuildEmote Emote = await Guild.CreateEmoteAsync(NameOfUser, EmoteImage); DiscordWebhookClient Webhook = await CreateOrGetWebhook(Context.Channel.Id, FunConfiguration.HeadpatWebhookName); await Webhook.SendMessageAsync( Emote.ToString(), username : string.IsNullOrEmpty(Context.Guild.GetUser(Context.User.Id).Nickname)?Context.User.Username : Context.Guild.GetUser(Context.User.Id).Nickname, avatarUrl : Context.User.GetTrueAvatarUrl() ); await Guild.DeleteEmoteAsync(Emote); } File.Delete(FilePath); }