Skip to content

Commit a54de9f

Browse files
committed
Optimize MediaManupliation file size
1 parent 29b42b2 commit a54de9f

2 files changed

Lines changed: 36 additions & 29 deletions

File tree

XeniaBot.Core/Modules/MediaManu/MediaManipulationModule.cs

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Discord;
22
using Discord.Interactions;
3+
using ImageMagick;
34
using NetVips;
45
using NLog;
56
using System;
@@ -16,7 +17,7 @@ public partial class MediaManipulationModule : InteractionModuleBase
1617
[SlashCommand("caption", "Add a caption to a piece of media")]
1718
public async Task Caption(string caption,
1819
IAttachment attachment,
19-
[Discord.Interactions.Summary(description: "Export as a GIF")]
20+
[Summary(description: "Export as a GIF")]
2021
bool saveAsGif = false)
2122
{
2223
await Context.Interaction.DeferAsync();
@@ -67,7 +68,7 @@ public async Task Caption(string caption,
6768

6869
// Create caption text
6970
var text = NVImage.Text(
70-
text: $"<span background=\"white\">{caption}</span>",
71+
text: $"<span background=\"white\">"+ caption.Replace("\\n", "\n") + "</span>",
7172
rgba: true,
7273
align: Enums.Align.Centre,
7374
font: $"FuturaExtraBlackCondensed {fontSize}px",
@@ -107,25 +108,28 @@ public async Task Caption(string caption,
107108
if (nPages > 1)
108109
i.Set("page-height", pageHeight + textHeight);
109110
});
110-
Log.Debug("Complete");
111-
if (isAnimated || saveAsGif)
112-
{
113-
using var gifStream = new MemoryStream(final.GifsaveBuffer(dither: 1, bitdepth: 8, interlace: true));
114-
await FollowupWithFileAsync(gifStream, $"{Context.Interaction.Id}.gif");
115-
}
116-
else
111+
112+
using var resultStream = new MemoryStream(isAnimated || saveAsGif
113+
? final.GifsaveBuffer(dither: 1, effort: 2, bitdepth: 8, interlace: true, reuse: true)
114+
: final.PngsaveBuffer(compression: 4, dither: 1, bitdepth: 8, interlace: true));
115+
var filename = isAnimated || saveAsGif ? $"{Context.Interaction.Id}.gif" : $"{Context.Interaction.Id}.png";
116+
var optimizer = new ImageOptimizer()
117117
{
118-
using var pngStream = new MemoryStream(final.PngsaveBuffer(compression: 4, dither: 1, bitdepth: 8, interlace: true));
119-
await FollowupWithFileAsync(pngStream, $"{Context.Interaction.Id}.png");
120-
}
118+
IgnoreUnsupportedFormats = true,
119+
OptimalCompression = true
120+
};
121+
resultStream.Seek(0, SeekOrigin.Begin);
122+
optimizer.Compress(resultStream);
123+
resultStream.Seek(0, SeekOrigin.Begin);
124+
Log.Debug($"Uploading file \"{filename}\" ({resultStream.Length}b)");
125+
await FollowupWithFileAsync(resultStream, filename);
121126
}
122127
catch (Exception ex)
123128
{
124129
Log.Error(ex);
125130
embed.WithDescription($"Failed to run task.\n```\n{ex.Message}\n```").WithColor(Color.Red);
126131
await FollowupAsync(embed: embed.Build());
127132
await DiscordHelper.ReportError(ex, Context);
128-
return;
129133
}
130134
}
131135

@@ -257,11 +261,11 @@ public async Task<NVImage> Watermark(NVImage source,
257261

258262
[SlashCommand("speechbubble", "Add a speech bubble to an image or a gif.")]
259263
public async Task SpeechBubble(IAttachment attachment,
260-
[Discord.Interactions.Summary(description: "When True, the speech bubble will be on the bottom, and when False it will be on top.")]
264+
[Summary(description: "When True, the speech bubble will be on the bottom, and when False it will be on top.")]
261265
bool flip = false,
262-
[Discord.Interactions.Summary(description: "When True, the speech bubble will have a transparent background, or it will have a white background")]
266+
[Summary(description: "When True, the speech bubble will have a transparent background, or it will have a white background")]
263267
bool alpha = false,
264-
[Discord.Interactions.Summary(description: "Export as a GIF")]
268+
[Summary(description: "Export as a GIF")]
265269
bool saveAsGif = false)
266270
{
267271
await Context.Interaction.DeferAsync();
@@ -307,27 +311,29 @@ public async Task SpeechBubble(IAttachment attachment,
307311
: NVImage.NewFromStream(MediaResources.ImageSpeechBubble));
308312
var final = await Watermark(
309313
sourceImage, watermark, 2, isAnimated, resize: true, yscale: 0.2f, alpha: alpha, flip: flip);
310-
311-
312-
Log.Debug($"Complete");
313-
if (isAnimated || saveAsGif)
314-
{
315-
using var gifStream = new MemoryStream(final.GifsaveBuffer(dither: 1, bitdepth: 8, interlace: true));
316-
await FollowupWithFileAsync(gifStream, $"{Context.Interaction.Id}.gif");
317-
}
318-
else
314+
315+
316+
using var resultStream = new MemoryStream(isAnimated || saveAsGif
317+
? final.GifsaveBuffer(dither: 1, effort: 2, bitdepth: 8, interlace: true, reuse: true)
318+
: final.PngsaveBuffer(compression: 4, dither: 1, bitdepth: 8, interlace: true));
319+
var filename = isAnimated || saveAsGif ? $"{Context.Interaction.Id}.gif" : $"{Context.Interaction.Id}.png";
320+
var optimizer = new ImageOptimizer()
319321
{
320-
using var pngStream = new MemoryStream(final.PngsaveBuffer(compression: 4, dither: 1, bitdepth: 8, interlace: true));
321-
await FollowupWithFileAsync(pngStream, $"{Context.Interaction.Id}.png");
322-
}
322+
IgnoreUnsupportedFormats = true,
323+
OptimalCompression = true
324+
};
325+
resultStream.Seek(0, SeekOrigin.Begin);
326+
optimizer.Compress(resultStream);
327+
resultStream.Seek(0, SeekOrigin.Begin);
328+
Log.Debug($"Uploading file \"{filename}\" ({resultStream.Length}b)");
329+
await FollowupWithFileAsync(resultStream, filename);
323330
}
324331
catch (Exception ex)
325332
{
326333
Log.Error(ex);
327334
embed.WithDescription($"Failed to run task.\n```\n{ex.Message}\n```").WithColor(Color.Red);
328335
await FollowupAsync(embed: embed.Build());
329336
await DiscordHelper.ReportError(ex, Context);
330-
return;
331337
}
332338
}
333339
}

XeniaBot.Core/XeniaBot.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
<PackageReference Include="DiffPlex" Version="1.9.0" />
6767
<PackageReference Include="Google.Cloud.Translation.V2" Version="3.4.0" />
6868
<PackageReference Include="IdGen" Version="3.0.7" />
69+
<PackageReference Include="Magick.NET-Q16-HDRI-AnyCPU" Version="14.9.1" />
6970
<PackageReference Include="MimeTypesMap" Version="1.0.9" />
7071
<PackageReference Include="Sentry.AspNetCore" Version="5.16.2" />
7172
</ItemGroup>

0 commit comments

Comments
 (0)