// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Reflection;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Quantization;
namespace SixLabors.ImageSharp.Tests.Formats;
public class GeneralFormatTests
{
///
/// A collection made up of one file for each image format.
///
public static readonly IEnumerable DefaultFiles =
new[]
{
TestImages.Bmp.Car,
TestImages.Jpeg.Baseline.Calliphora,
TestImages.Png.Splash,
TestImages.Gif.Trans
};
///
/// The collection of image files to test against.
///
protected static readonly List Files = new()
{
TestFile.Create(TestImages.Jpeg.Baseline.Calliphora),
TestFile.Create(TestImages.Bmp.Car),
TestFile.Create(TestImages.Png.Splash),
TestFile.Create(TestImages.Gif.Rings),
};
[Theory]
[WithFileCollection(nameof(DefaultFiles), PixelTypes.Rgba32)]
public void ResolutionShouldChange(TestImageProvider provider)
where TPixel : unmanaged, IPixel
{
using Image image = provider.GetImage();
image.Metadata.VerticalResolution = 150;
image.Metadata.HorizontalResolution = 150;
image.DebugSave(provider);
}
[Fact]
public void ReadOriginIsRespectedOnLoad()
{
using FileStream stream = File.OpenRead(TestFile.GetInputFileFullPath(TestImages.Png.Issue2259));
using Image i = Image.Load(stream);
long position1 = stream.Position;
Assert.NotEqual(0, position1);
using Image j = Image.Load(stream);
long position2 = stream.Position;
Assert.True(position2 > position1);
Assert.NotEqual(i[5, 5], j[5, 5]);
}
[Fact]
public async Task ReadOriginIsRespectedOnLoadAsync()
{
using FileStream stream = File.OpenRead(TestFile.GetInputFileFullPath(TestImages.Png.Issue2259));
using Image i = await Image.LoadAsync(stream);
long position1 = stream.Position;
Assert.NotEqual(0, position1);
using Image j = await Image.LoadAsync(stream);
long position2 = stream.Position;
Assert.True(position2 > position1);
Assert.NotEqual(i[5, 5], j[5, 5]);
}
[Fact]
public void ImageCanEncodeToString()
{
string path = TestEnvironment.CreateOutputDirectory("ToString");
foreach (TestFile file in Files)
{
using Image image = file.CreateRgba32Image();
string filename = Path.Combine(path, $"{file.FileNameWithoutExtension}.txt");
File.WriteAllText(filename, image.ToBase64String(PngFormat.Instance));
}
}
[Fact]
public void DecodeThenEncodeImageFromStreamShouldSucceed()
{
string path = TestEnvironment.CreateOutputDirectory("Encode");
foreach (TestFile file in Files)
{
using Image image = file.CreateRgba32Image();
image.Save(Path.Combine(path, file.FileName));
}
}
public static readonly TheoryData QuantizerNames =
new()
{
nameof(KnownQuantizers.Octree),
nameof(KnownQuantizers.WebSafe),
nameof(KnownQuantizers.Werner),
nameof(KnownQuantizers.Wu)
};
[Theory]
[WithFile(TestImages.Png.CalliphoraPartial, nameof(QuantizerNames), PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Bike, nameof(QuantizerNames), PixelTypes.Rgba32)]
public void QuantizeImageShouldPreserveMaximumColorPrecision(TestImageProvider provider, string quantizerName)
where TPixel : unmanaged, IPixel
{
IQuantizer quantizer = GetQuantizer(quantizerName);
using (Image image = provider.GetImage())
{
image.DebugSave(provider, new PngEncoder { ColorType = PngColorType.Palette, Quantizer = quantizer }, testOutputDetails: quantizerName);
}
provider.Configuration.MemoryAllocator.ReleaseRetainedResources();
}
private static IQuantizer GetQuantizer(string name)
{
PropertyInfo property = typeof(KnownQuantizers).GetTypeInfo().GetProperty(name);
return (IQuantizer)property.GetMethod.Invoke(null, Array.Empty