📷 A modern, cross-platform, 2D Graphics library for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

265 lines
11 KiB

// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.IO;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit;
using static SixLabors.ImageSharp.Tests.TestImages.Webp;
namespace SixLabors.ImageSharp.Tests.Formats.Webp
{
[Collection("RunSerial")]
[Trait("Format", "Webp")]
public class WebpEncoderTests
{
[Theory]
[WithFile(Flag, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.PalettedTwoColor, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Paletted256Colors, PixelTypes.Rgba32)]
public void Encode_Lossless_WithPalette_Works<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = false,
Quality = 100,
Method = WebpEncodingMethod.BestQuality
};
using Image<TPixel> image = provider.GetImage();
image.VerifyEncoder(provider, "webp", string.Empty, encoder);
}
[Theory]
[WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 100)]
[WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 80)]
[WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 20)]
public void Encode_Lossless_WithDifferentQuality_Works<TPixel>(TestImageProvider<TPixel> provider, int quality)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = false,
Quality = quality
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("lossless", "_q", quality);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder);
}
[Theory]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 100)]
public void Encode_Lossless_WithDifferentMethodAndQuality_Works<TPixel>(TestImageProvider<TPixel> provider, WebpEncodingMethod method, int quality)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = false,
Method = method,
Quality = quality
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("lossless", "_m", method, "_q", quality);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder);
}
[Theory]
[WithFile(RgbTestPattern100x100, PixelTypes.Rgba32, 85)]
[WithFile(RgbTestPattern100x100, PixelTypes.Rgba32, 60)]
[WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 40)]
[WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 20)]
[WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 10)]
[WithFile(RgbTestPattern63x63, PixelTypes.Rgba32, 40)]
public void Encode_Lossless_WithNearLosslessFlag_Works<TPixel>(TestImageProvider<TPixel> provider, int nearLosslessQuality)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = false,
NearLossless = true,
NearLosslessQuality = nearLosslessQuality
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("nearlossless", "_q", nearLosslessQuality);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(nearLosslessQuality));
}
[Theory]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6)]
[WithFile(Lossy.Alpha1, PixelTypes.Rgba32, 4)]
public void Encode_Lossless_WithPreserveTransparentColor_Works<TPixel>(TestImageProvider<TPixel> provider, WebpEncodingMethod method)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = false,
Method = method,
TransparentColorMode = WebpTransparentColorMode.Preserve
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("lossless", "_m", method);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder);
}
[Theory]
[WithFile(TestPatternOpaque, PixelTypes.Rgba32)]
[WithFile(TestPatternOpaqueSmall, PixelTypes.Rgba32)]
public void Encode_Lossless_WorksWithTestPattern<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage();
var encoder = new WebpEncoder() { Lossy = false };
image.VerifyEncoder(provider, "webp", string.Empty, encoder);
}
[Fact]
public void Encode_Lossless_OneByOnePixel_Works()
{
// Just make sure, encoding 1 pixel by 1 pixel does not throw an exception.
using var image = new Image<Rgba32>(1, 1);
var encoder = new WebpEncoder() { Lossy = false };
using (var memStream = new MemoryStream())
{
image.SaveAsWebp(memStream, encoder);
}
}
[Theory]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 20)]
public void Encode_Lossy_WithDifferentQuality_Works<TPixel>(TestImageProvider<TPixel> provider, int quality)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = true,
Quality = quality
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("lossy", "_q", quality);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(quality));
}
[Theory]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 80)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 50)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 30)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 10)]
public void Encode_Lossy_WithDifferentFilterStrength_Works<TPixel>(TestImageProvider<TPixel> provider, int filterStrength)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = true,
FilterStrength = filterStrength
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("lossy", "_f", filterStrength);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(75));
}
[Theory]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 80)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 50)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 30)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 10)]
public void Encode_Lossy_WithDifferentSpatialNoiseShapingStrength_Works<TPixel>(TestImageProvider<TPixel> provider, int snsStrength)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = true,
SpatialNoiseShaping = snsStrength
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("lossy", "_sns", snsStrength);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(75));
}
[Theory]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 75)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 100)]
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 100)]
public void Encode_Lossy_WithDifferentMethodsAndQuality_Works<TPixel>(TestImageProvider<TPixel> provider, WebpEncodingMethod method, int quality)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
Lossy = true,
Method = method,
Quality = quality
};
using Image<TPixel> image = provider.GetImage();
string testOutputDetails = string.Concat("lossy", "_m", method, "_q", quality);
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(quality));
}
[Theory]
[WithFile(TestPatternOpaque, PixelTypes.Rgba32)]
[WithFile(TestPatternOpaqueSmall, PixelTypes.Rgba32)]
public void Encode_Lossy_WorksWithTestPattern<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage();
var encoder = new WebpEncoder() { Lossy = true };
image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.Tolerant(0.04f));
}
private static ImageComparer GetComparer(int quality)
{
float tolerance = 0.01f; // ~1.0%
if (quality < 30)
{
tolerance = 0.02f; // ~2.0%
}
return ImageComparer.Tolerant(tolerance);
}
}
}