From a84160be9f1993bc43d84faa5ec14c567e432212 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 27 Mar 2025 13:07:08 +1000 Subject: [PATCH] Add new benchmarks --- .../Quantization/QuantizerOptions.cs | 5 +- .../Codecs/Gif/DecodeEncodeGif.cs | 59 +++++++++++++++++++ .../Codecs/Gif/EncodeGif.cs | 26 +++++--- 3 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeEncodeGif.cs diff --git a/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs b/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs index 7a66204c64..85db2b7c4e 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs @@ -10,9 +10,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization; /// public class QuantizerOptions { +#pragma warning disable IDE0032 // Use auto property private float ditherScale = QuantizerConstants.MaxDitherScale; private int maxColors = QuantizerConstants.MaxColors; private float threshold = QuantizerConstants.DefaultTransparencyThreshold; +#pragma warning restore IDE0032 // Use auto property /// /// Gets or sets the algorithm to apply to the output image. @@ -58,6 +60,7 @@ public class QuantizerOptions /// /// Gets or sets the color matching mode used for matching pixel values to palette colors. + /// Defaults to . /// - public ColorMatchingMode ColorMatchingMode { get; set; } = ColorMatchingMode.Hybrid; + public ColorMatchingMode ColorMatchingMode { get; set; } = ColorMatchingMode.Coarse; } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeEncodeGif.cs b/tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeEncodeGif.cs new file mode 100644 index 0000000000..3238e8dac2 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeEncodeGif.cs @@ -0,0 +1,59 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Drawing.Imaging; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Gif; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using SixLabors.ImageSharp.Tests; +using SDImage = System.Drawing.Image; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs; + +public abstract class DecodeEncodeGif +{ + private MemoryStream outputStream; + + protected abstract GifEncoder Encoder { get; } + + [Params(TestImages.Gif.Leo, TestImages.Gif.Cheers)] + public string TestImage { get; set; } + + private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [GlobalSetup] + public void Setup() => this.outputStream = new MemoryStream(); + + [GlobalCleanup] + public void Cleanup() => this.outputStream.Close(); + + [Benchmark(Baseline = true)] + public void SystemDrawing() + { + this.outputStream.Position = 0; + using SDImage image = SDImage.FromFile(this.TestImageFullPath); + image.Save(this.outputStream, ImageFormat.Gif); + } + + [Benchmark] + public void ImageSharp() + { + this.outputStream.Position = 0; + using Image image = Image.Load(this.TestImageFullPath); + image.SaveAsGif(this.outputStream, this.Encoder); + } +} + +public class DecodeEncodeGif_DefaultEncoder : DecodeEncodeGif +{ + protected override GifEncoder Encoder => new(); +} + +public class DecodeEncodeGif_CoarsePaletteEncoder : DecodeEncodeGif +{ + protected override GifEncoder Encoder => new() + { + Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4, ColorMatchingMode = ColorMatchingMode.Coarse }) + }; +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs b/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs index beedbbe07c..2b2428210a 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs @@ -12,21 +12,16 @@ using SDImage = System.Drawing.Image; namespace SixLabors.ImageSharp.Benchmarks.Codecs; -[Config(typeof(Config.Short))] -public class EncodeGif +public abstract class EncodeGif { // System.Drawing needs this. private FileStream bmpStream; private SDImage bmpDrawing; private Image bmpCore; - // Try to get as close to System.Drawing's output as possible - private readonly GifEncoder encoder = new() - { - Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4 }) - }; + protected abstract GifEncoder Encoder { get; } - [Params(TestImages.Bmp.Car, TestImages.Png.Rgb48Bpp)] + [Params(TestImages.Gif.Leo, TestImages.Gif.Cheers)] public string TestImage { get; set; } [GlobalSetup] @@ -61,6 +56,19 @@ public class EncodeGif public void GifImageSharp() { using MemoryStream memoryStream = new(); - this.bmpCore.SaveAsGif(memoryStream, this.encoder); + this.bmpCore.SaveAsGif(memoryStream, this.Encoder); } } + +public class EncodeGif_DefaultEncoder : EncodeGif +{ + protected override GifEncoder Encoder => new(); +} + +public class EncodeGif_CoarsePaletteEncoder : EncodeGif +{ + protected override GifEncoder Encoder => new() + { + Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4, ColorMatchingMode = ColorMatchingMode.Coarse }) + }; +}