// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using ImageMagick; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Normalization; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; namespace SixLabors.ImageSharp.Tests.Processing.Normalization; // ReSharper disable InconsistentNaming [Trait("Category", "Processors")] public class MagickCompareTests { [Theory] [WithFile(TestImages.Jpeg.Baseline.ForestBridgeDifferentComponentsQuality, PixelTypes.Rgba32)] public void AutoLevel_CompareToMagick(TestImageProvider provider) where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel { Image imageFromMagick; using (Stream stream = LoadAsStream(provider)) { using MagickImage magickImage = new(stream); // Apply Auto Level using the Grey (BT.709) channel. magickImage.AutoLevel(Channels.Gray); imageFromMagick = ConvertImageFromMagick(magickImage); } using Image image = provider.GetImage(); HistogramEqualizationOptions options = new() { Method = HistogramEqualizationMethod.AutoLevel, LuminanceLevels = 256, SyncChannels = true }; image.Mutate(x => x.HistogramEqualization(options)); image.DebugSave(provider); ExactImageComparer.Instance.CompareImages(imageFromMagick, image); imageFromMagick.Dispose(); } private static FileStream LoadAsStream(TestImageProvider provider) where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel { string path = TestImageProvider.GetFilePathOrNull(provider) ?? throw new InvalidOperationException("CompareToMagick() works only with file providers!"); TestFile testFile = TestFile.Create(path); return new FileStream(testFile.FullPath, FileMode.Open); } private static Image ConvertImageFromMagick(MagickImage magickImage) where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel { Configuration configuration = Configuration.Default.Clone(); configuration.PreferContiguousImageBuffers = true; Image result = new(configuration, (int)magickImage.Width, (int)magickImage.Height); Assert.True(result.DangerousTryGetSinglePixelMemory(out Memory resultPixels)); using (IUnsafePixelCollection pixels = magickImage.GetPixelsUnsafe()) { byte[] data = pixels.ToByteArray(PixelMapping.RGBA); PixelOperations.Instance.FromRgba32Bytes( configuration, data, resultPixels.Span, resultPixels.Length); } return result; } }