diff --git a/src/ImageSharp/Formats/Webp/IWebpEncoderOptions.cs b/src/ImageSharp/Formats/Webp/IWebpEncoderOptions.cs index 63d76a598..5059ac73e 100644 --- a/src/ImageSharp/Formats/Webp/IWebpEncoderOptions.cs +++ b/src/ImageSharp/Formats/Webp/IWebpEncoderOptions.cs @@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Formats.Webp /// Gets a value indicating whether lossy compression should be used. /// If false, lossless compression will be used. /// - bool Lossy { get; } + bool? Lossy { get; } /// /// Gets the compression quality. Between 0 and 100. diff --git a/src/ImageSharp/Formats/Webp/WebpEncoder.cs b/src/ImageSharp/Formats/Webp/WebpEncoder.cs index 1b1dab784..1667eb1db 100644 --- a/src/ImageSharp/Formats/Webp/WebpEncoder.cs +++ b/src/ImageSharp/Formats/Webp/WebpEncoder.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Webp public sealed class WebpEncoder : IImageEncoder, IWebpEncoderOptions { /// - public bool Lossy { get; set; } + public bool? Lossy { get; set; } /// public int Quality { get; set; } = 75; diff --git a/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs b/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs index ff0246cdd..3be5409b1 100644 --- a/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs +++ b/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs @@ -4,9 +4,11 @@ using System.IO; using System.Threading; using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.Formats.Webp.Lossless; using SixLabors.ImageSharp.Formats.Webp.Lossy; using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Webp @@ -27,11 +29,6 @@ namespace SixLabors.ImageSharp.Formats.Webp /// private readonly bool alphaCompression; - /// - /// Indicating whether lossy compression should be used. If false, lossless compression will be used. - /// - private readonly bool lossy; - /// /// Compression quality. Between 0 and 100. /// @@ -73,6 +70,11 @@ namespace SixLabors.ImageSharp.Formats.Webp /// private readonly int nearLosslessQuality; + /// + /// Indicating whether lossy compression should be used. If false, lossless compression will be used. + /// + private bool? lossy; + /// /// The global configuration. /// @@ -112,8 +114,11 @@ namespace SixLabors.ImageSharp.Formats.Webp Guard.NotNull(stream, nameof(stream)); this.configuration = image.GetConfiguration(); + ImageMetadata metadata = image.Metadata; + WebpMetadata webpMetadata = metadata.GetWebpMetadata(); + this.lossy ??= webpMetadata.Format == WebpFormatType.Lossy; - if (this.lossy) + if (this.lossy.GetValueOrDefault()) { using var enc = new Vp8Encoder( this.memoryAllocator, diff --git a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs index 80d48d0ca..b48020198 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs @@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp }; // Convert image pixels to bgra array. - byte[] imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.Webp.Lossless.BikeSmall)); + byte[] imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.Webp.Lossy.BikeSmall)); using var image = Image.Load(imgBytes, new WebpDecoder()); uint[] bgra = ToBgra(image); diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs index 70bf3e66c..de5a6171a 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs @@ -3,6 +3,7 @@ using System.IO; using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; @@ -14,6 +15,26 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Trait("Format", "Webp")] public class WebpEncoderTests { + [Theory] + [WithFile(Flag, PixelTypes.Rgba32, WebpFormatType.Lossless)] // if its not a webp input image, it should default to lossless. + [WithFile(Lossless.NoTransform1, PixelTypes.Rgba32, WebpFormatType.Lossless)] + [WithFile(Lossy.Bike, PixelTypes.Rgba32, WebpFormatType.Lossy)] + public void Encode_PreserveRatio(TestImageProvider provider, WebpFormatType expectedFormat) + where TPixel : unmanaged, IPixel + { + var options = new WebpEncoder(); + using Image input = provider.GetImage(); + using var memoryStream = new MemoryStream(); + input.Save(memoryStream, options); + + memoryStream.Position = 0; + using var output = Image.Load(memoryStream); + + ImageMetadata meta = output.Metadata; + WebpMetadata webpMetaData = meta.GetWebpMetadata(); + Assert.Equal(expectedFormat, webpMetaData.Format); + } + [Theory] [WithFile(Flag, PixelTypes.Rgba32)] [WithFile(TestImages.Png.PalettedTwoColor, PixelTypes.Rgba32)] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index a9af84f9b..116c5adc3 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -603,8 +603,6 @@ namespace SixLabors.ImageSharp.Tests // substract_green, predictor, cross_color public const string BikeThreeTransforms = "Webp/bike_lossless.webp"; - public const string BikeSmall = "Webp/bike_lossless_small.webp"; - // Invalid / corrupted images // Below images have errors according to webpinfo. The error message webpinfo gives is "Truncated data detected when parsing RIFF payload." public const string LossLessCorruptImage1 = "Webp/lossless_big_random_alpha.webp"; // substract_green, predictor, cross_color. @@ -621,6 +619,7 @@ namespace SixLabors.ImageSharp.Tests public const string Earth = "Webp/earth_lossy.webp"; public const string WithExif = "Webp/exif_lossy.webp"; public const string WithIccp = "Webp/lossy_with_iccp.webp"; + public const string BikeSmall = "Webp/bike_lossless_small.webp"; // Lossy images without macroblock filtering. public const string Bike = "Webp/bike_lossy.webp";