private static void TestPngEncoderCore <TPixel>( TestImageProvider <TPixel> provider, PngColorType pngColorType, PngFilterMethod pngFilterMethod, int compressionLevel = 6, int paletteSize = 255, bool appendPngColorType = false, bool appendPngFilterMethod = false, bool appendPixelType = false, bool appendCompressionLevel = false, bool appendPaletteSize = false) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) { if (!HasAlpha(pngColorType)) { image.Mutate(c => c.MakeOpaque()); } var encoder = new PngEncoder { PngColorType = pngColorType, PngFilterMethod = pngFilterMethod, CompressionLevel = compressionLevel, Quantizer = new WuQuantizer(paletteSize) }; string pngColorTypeInfo = appendPngColorType ? pngColorType.ToString() : string.Empty; string pngFilterMethodInfo = appendPngFilterMethod ? pngFilterMethod.ToString() : string.Empty; string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : string.Empty; string paletteSizeInfo = appendPaletteSize ? $"_PaletteSize-{paletteSize}" : string.Empty; string debugInfo = $"{pngColorTypeInfo}{pngFilterMethodInfo}{compressionLevelInfo}{paletteSizeInfo}"; //string referenceInfo = $"{pngColorTypeInfo}"; // Does DebugSave & load reference CompareToReferenceInput(): string actualOutputFile = ((ITestImageProvider)provider).Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType); if (TestEnvironment.IsMono) { // There are bugs in mono's System.Drawing implementation, reference decoders are not always reliable! return; } IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile); string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", debugInfo, appendPixelType, true); using (var actualImage = Image.Load <TPixel>(actualOutputFile, referenceDecoder)) using (var referenceImage = Image.Load <TPixel>(referenceOutputFile, referenceDecoder)) { float paletteToleranceHack = 80f / paletteSize; paletteToleranceHack = paletteToleranceHack * paletteToleranceHack; ImageComparer comparer = pngColorType == PngColorType.Palette ? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder * paletteToleranceHack) : ImageComparer.Exact; comparer.VerifySimilarity(referenceImage, actualImage); } } }
private static void TestPngEncoderCore <TPixel>( TestImageProvider <TPixel> provider, PngColorType pngColorType, PngFilterMethod pngFilterMethod, PngBitDepth bitDepth, PngInterlaceMode interlaceMode, PngCompressionLevel compressionLevel = PngCompressionLevel.DefaultCompression, int paletteSize = 255, bool appendPngColorType = false, bool appendPngFilterMethod = false, bool appendPixelType = false, bool appendCompressionLevel = false, bool appendPaletteSize = false, bool appendPngBitDepth = false, PngChunkFilter optimizeMethod = PngChunkFilter.None) where TPixel : unmanaged, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) { var encoder = new PngEncoder { ColorType = pngColorType, FilterMethod = pngFilterMethod, CompressionLevel = compressionLevel, BitDepth = bitDepth, Quantizer = new WuQuantizer(new QuantizerOptions { MaxColors = paletteSize }), InterlaceMethod = interlaceMode, ChunkFilter = optimizeMethod, }; string pngColorTypeInfo = appendPngColorType ? pngColorType.ToString() : string.Empty; string pngFilterMethodInfo = appendPngFilterMethod ? pngFilterMethod.ToString() : string.Empty; string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : string.Empty; string paletteSizeInfo = appendPaletteSize ? $"_PaletteSize-{paletteSize}" : string.Empty; string pngBitDepthInfo = appendPngBitDepth ? bitDepth.ToString() : string.Empty; string pngInterlaceModeInfo = interlaceMode != PngInterlaceMode.None ? $"_{interlaceMode}" : string.Empty; string debugInfo = $"{pngColorTypeInfo}{pngFilterMethodInfo}{compressionLevelInfo}{paletteSizeInfo}{pngBitDepthInfo}{pngInterlaceModeInfo}"; string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType); // Compare to the Magick reference decoder. IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile); // We compare using both our decoder and the reference decoder as pixel transformation // occurs within the encoder itself leaving the input image unaffected. // This means we are benefiting from testing our decoder also. using (var imageSharpImage = Image.Load <TPixel>(actualOutputFile, new PngDecoder())) using (var referenceImage = Image.Load <TPixel>(actualOutputFile, referenceDecoder)) { ImageComparer.Exact.VerifySimilarity(referenceImage, imageSharpImage); } } }
/// <summary> /// Initializes a new instance of the <see cref="PngEncoderCore"/> class. /// </summary> /// <param name="memoryAllocator">The <see cref="MemoryAllocator"/> to use for buffer allocations.</param> /// <param name="options">The options for influencing the encoder</param> public PngEncoderCore(MemoryAllocator memoryAllocator, IPngEncoderOptions options) { this.memoryAllocator = memoryAllocator; this.pngColorType = options.PngColorType; this.pngFilterMethod = options.PngFilterMethod; this.compressionLevel = options.CompressionLevel; this.gamma = options.Gamma; this.quantizer = options.Quantizer; this.threshold = options.Threshold; this.writeGamma = options.WriteGamma; }
/// <summary> /// Initializes a new instance of the <see cref="PngEncoderCore"/> class. /// </summary> /// <param name="memoryAllocator">The <see cref="MemoryAllocator"/> to use for buffer allocations.</param> /// <param name="options">The options for influencing the encoder</param> public PngEncoderCore(MemoryAllocator memoryAllocator, IPngEncoderOptions options) { this.memoryAllocator = memoryAllocator; this.pngBitDepth = options.BitDepth; this.pngColorType = options.ColorType; // Specification recommends default filter method None for paletted images and Paeth for others. this.pngFilterMethod = options.FilterMethod ?? (options.ColorType.Equals(PngColorType.Palette) ? PngFilterMethod.None : PngFilterMethod.Paeth); this.compressionLevel = options.CompressionLevel; this.gamma = options.Gamma; this.quantizer = options.Quantizer; this.threshold = options.Threshold; }
public void WorksWithAllFilterMethods <TPixel>(TestImageProvider <TPixel> provider, PngFilterMethod pngFilterMethod) where TPixel : unmanaged, IPixel <TPixel> { foreach (PngInterlaceMode interlaceMode in InterlaceMode) { TestPngEncoderCore( provider, PngColorType.RgbWithAlpha, pngFilterMethod, PngBitDepth.Bit8, interlaceMode, appendPngFilterMethod: true); } }
public void WorksWithAllFilterMethods <TPixel>(TestImageProvider <TPixel> provider, PngFilterMethod pngFilterMethod) where TPixel : struct, IPixel <TPixel> { TestPngEncoderCore( provider, PngColorType.RgbWithAlpha, pngFilterMethod, PngBitDepth.Bit8, appendPngFilterMethod: true); }