Browse Source

Preserve lossy/lossless encoding, if input image was webp

pull/1552/head
Brian Popow 4 years ago
parent
commit
bc4e2f7237
  1. 2
      src/ImageSharp/Formats/Webp/IWebpEncoderOptions.cs
  2. 2
      src/ImageSharp/Formats/Webp/WebpEncoder.cs
  3. 17
      src/ImageSharp/Formats/Webp/WebpEncoderCore.cs
  4. 2
      tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs
  5. 21
      tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs
  6. 3
      tests/ImageSharp.Tests/TestImages.cs

2
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.
/// </summary>
bool Lossy { get; }
bool? Lossy { get; }
/// <summary>
/// Gets the compression quality. Between 0 and 100.

2
src/ImageSharp/Formats/Webp/WebpEncoder.cs

@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Webp
public sealed class WebpEncoder : IImageEncoder, IWebpEncoderOptions
{
/// <inheritdoc/>
public bool Lossy { get; set; }
public bool? Lossy { get; set; }
/// <inheritdoc/>
public int Quality { get; set; } = 75;

17
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
/// </summary>
private readonly bool alphaCompression;
/// <summary>
/// Indicating whether lossy compression should be used. If false, lossless compression will be used.
/// </summary>
private readonly bool lossy;
/// <summary>
/// Compression quality. Between 0 and 100.
/// </summary>
@ -73,6 +70,11 @@ namespace SixLabors.ImageSharp.Formats.Webp
/// </summary>
private readonly int nearLosslessQuality;
/// <summary>
/// Indicating whether lossy compression should be used. If false, lossless compression will be used.
/// </summary>
private bool? lossy;
/// <summary>
/// The global configuration.
/// </summary>
@ -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,

2
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<Rgba32>(imgBytes, new WebpDecoder());
uint[] bgra = ToBgra(image);

21
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<TPixel>(TestImageProvider<TPixel> provider, WebpFormatType expectedFormat)
where TPixel : unmanaged, IPixel<TPixel>
{
var options = new WebpEncoder();
using Image<TPixel> input = provider.GetImage();
using var memoryStream = new MemoryStream();
input.Save(memoryStream, options);
memoryStream.Position = 0;
using var output = Image.Load<Rgba32>(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)]

3
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";

Loading…
Cancel
Save