diff --git a/zero/Media/ImageSharp/Processors/LoopWebProcessor.cs b/zero/Media/ImageSharp/Processors/LoopWebProcessor.cs new file mode 100644 index 00000000..a08ea0b6 --- /dev/null +++ b/zero/Media/ImageSharp/Processors/LoopWebProcessor.cs @@ -0,0 +1,64 @@ +using Microsoft.Extensions.Logging; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Web; +using SixLabors.ImageSharp.Web.Commands; +using SixLabors.ImageSharp.Web.Processors; +using System.Globalization; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Gif; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.Formats.Webp; + +namespace zero.Media.ImageSharp.Processors; + +public class LoopWebProcessor : IImageWebProcessor +{ + // + /// The command constant for the loop prop. + /// + public const string Loop = "loop"; + + /// + /// The reusable collection of commands. + /// + private static readonly IEnumerable LoopCommands = [Loop]; + + /// + public IEnumerable Commands { get; } = LoopCommands; + + /// + public FormattedImage Process( + FormattedImage image, + ILogger logger, + CommandCollection commands, + CommandParser parser, + CultureInfo culture) + { + if (commands.Contains(Loop)) + { + SixLabors.ImageSharp.Metadata.ImageMetadata metadata = image.Image.Metadata; + bool loop = parser.ParseValue(commands.GetValueOrDefault(Loop), culture); + + if (!loop) + { + if (metadata.TryGetWebpMetadata(out WebpMetadata webpMetadata)) + { + webpMetadata.RepeatCount = 1; + } + if (metadata.TryGetGifMetadata(out GifMetadata gifMetadata)) + { + gifMetadata.RepeatCount = 1; + } + if (metadata.TryGetPngMetadata(out PngMetadata pngMetadata)) + { + pngMetadata.RepeatCount = 1; + } + } + } + + return image; + } + + /// + public bool RequiresTrueColorPixelFormat(CommandCollection commands, CommandParser parser, CultureInfo culture) => true; +} diff --git a/zero/Media/ImageSharp/Processors/StripMetadataWebProcessor.cs b/zero/Media/ImageSharp/Processors/StripMetadataWebProcessor.cs index f2d77384..be2413fc 100644 --- a/zero/Media/ImageSharp/Processors/StripMetadataWebProcessor.cs +++ b/zero/Media/ImageSharp/Processors/StripMetadataWebProcessor.cs @@ -16,8 +16,7 @@ public class StripMetadataWebProcessor : IImageWebProcessor /// /// The reusable collection of commands. /// - private static readonly IEnumerable StripCommands - = new[] { Strip }; + private static readonly IEnumerable StripCommands = [Strip]; /// public IEnumerable Commands { get; } = StripCommands; diff --git a/zero/Media/ZeroMediaModule.cs b/zero/Media/ZeroMediaModule.cs index 60c258d8..4e4efd51 100644 --- a/zero/Media/ZeroMediaModule.cs +++ b/zero/Media/ZeroMediaModule.cs @@ -22,7 +22,8 @@ internal class ZeroMediaModule : ZeroModule .AddProvider() .AddProcessor() .AddProcessor() - .AddProcessor(); + .AddProcessor() + .AddProcessor(); services.AddOptions().Configure(opts => {