public void OrderedDitherEquality() { IDither dither = KnownDitherings.Bayer2x2; OrderedDither dither2 = OrderedDither.Bayer2x2; OrderedDither dither3 = OrderedDither.Bayer2x2; Assert.True(dither == dither2); Assert.True(dither2 == dither); Assert.False(dither != dither2); Assert.False(dither2 != dither); Assert.Equal(dither, dither2); Assert.Equal(dither, (object)dither2); Assert.Equal(dither.GetHashCode(), dither2.GetHashCode()); dither = null; Assert.False(dither == dither2); Assert.False(dither2 == dither); Assert.True(dither != dither2); Assert.True(dither2 != dither); Assert.NotEqual(dither, dither2); Assert.NotEqual(dither, (object)dither2); Assert.NotEqual(dither?.GetHashCode(), dither2.GetHashCode()); Assert.True(dither2 == dither3); Assert.True(dither3 == dither2); Assert.False(dither2 != dither3); Assert.False(dither3 != dither2); Assert.Equal(dither2, dither3); Assert.Equal(dither2, (object)dither3); Assert.Equal(dither2.GetHashCode(), dither3.GetHashCode()); }
public void ErrorDitherEquality() { IDither dither = KnownDitherings.FloydSteinberg; ErrorDither dither2 = ErrorDither.FloydSteinberg; ErrorDither dither3 = ErrorDither.FloydSteinberg; Assert.True(dither == dither2); Assert.True(dither2 == dither); Assert.False(dither != dither2); Assert.False(dither2 != dither); Assert.Equal(dither, dither2); Assert.Equal(dither, (object)dither2); Assert.Equal(dither.GetHashCode(), dither2.GetHashCode()); dither = null; Assert.False(dither == dither2); Assert.False(dither2 == dither); Assert.True(dither != dither2); Assert.True(dither2 != dither); Assert.NotEqual(dither, dither2); Assert.NotEqual(dither, (object)dither2); Assert.NotEqual(dither?.GetHashCode(), dither2.GetHashCode()); Assert.True(dither2 == dither3); Assert.True(dither3 == dither2); Assert.False(dither2 != dither3); Assert.False(dither3 != dither2); Assert.Equal(dither2, dither3); Assert.Equal(dither2, (object)dither3); Assert.Equal(dither2.GetHashCode(), dither3.GetHashCode()); }
/// <summary> /// Dithers the image reducing it to the given palette using ordered dithering. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="dither">The ordered ditherer.</param> /// <param name="ditherScale">The dithering scale used to adjust the amount of dither.</param> /// <param name="palette">The palette to select substitute colors from.</param> /// <param name="rectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// </param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext Dither( this IImageProcessingContext source, IDither dither, float ditherScale, ReadOnlyMemory <Color> palette, Rectangle rectangle) => source.ApplyProcessor(new PaletteDitherProcessor(dither, ditherScale, palette), rectangle);
/// <summary> /// Dithers the image reducing it to two colors using ordered dithering. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="dither">The ordered ditherer.</param> /// <param name="upperColor">The color to use for pixels that are above the threshold.</param> /// <param name="lowerColor">The color to use for pixels that are below the threshold</param> /// <param name="rectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// </param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext BinaryDither( this IImageProcessingContext source, IDither dither, Color upperColor, Color lowerColor, Rectangle rectangle) => source.ApplyProcessor(new PaletteDitherProcessor(dither, new[] { upperColor, lowerColor }), rectangle);
/// <summary> /// Initializes a new instance of the <see cref="PaletteDitherProcessor"/> class. /// </summary> /// <param name="dither">The dithering algorithm.</param> /// <param name="ditherScale">The dithering scale used to adjust the amount of dither.</param> /// <param name="palette">The palette to select substitute colors from.</param> public PaletteDitherProcessor(IDither dither, float ditherScale, ReadOnlyMemory <Color> palette) { Guard.MustBeGreaterThan(palette.Length, 0, nameof(palette)); Guard.NotNull(dither, nameof(dither)); this.Dither = dither; this.DitherScale = ditherScale.Clamp(QuantizerConstants.MinDitherScale, QuantizerConstants.MaxDitherScale); this.Palette = palette; }
/// <summary> /// Initializes a new instance of the <see cref="PaletteDitherProcessor{TPixel}"/> class. /// </summary> /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param> /// <param name="definition">The <see cref="PaletteDitherProcessor"/> defining the processor parameters.</param> /// <param name="source">The source <see cref="Image{TPixel}"/> for the current processor instance.</param> /// <param name="sourceRectangle">The source area to process for the current processor instance.</param> public PaletteDitherProcessor(Configuration configuration, PaletteDitherProcessor definition, Image <TPixel> source, Rectangle sourceRectangle) : base(configuration, source, sourceRectangle) { this.paletteLength = definition.Palette.Span.Length; this.dither = definition.Dither; this.ditherScale = definition.DitherScale; this.sourcePalette = definition.Palette; }
public void ShouldThrowForDefaultDitherInstance(IDither dither) { void Command() { using var image = new Image <Rgba32>(10, 10); image.Mutate(x => x.Dither(dither)); } Assert.Throws <ImageProcessingException>(Command); }
public void ShouldThrowForDefaultDitherInstance(IDither dither) { void Command() { using var image = new Image <Rgba32>(10, 10); var quantizer = new WebSafePaletteQuantizer(); quantizer.Options.Dither = dither; image.Mutate(x => x.Quantize(quantizer)); } Assert.Throws <ImageProcessingException>(Command); }
/// <summary> /// Initializes a new instance of the <see cref="PaletteDitherProcessor{TPixel}"/> class. /// </summary> /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param> /// <param name="definition">The <see cref="PaletteDitherProcessor"/> defining the processor parameters.</param> /// <param name="source">The source <see cref="Image{TPixel}"/> for the current processor instance.</param> /// <param name="sourceRectangle">The source area to process for the current processor instance.</param> public PaletteDitherProcessor(Configuration configuration, PaletteDitherProcessor definition, Image <TPixel> source, Rectangle sourceRectangle) : base(configuration, source, sourceRectangle) { this.dither = definition.Dither; ReadOnlySpan <Color> sourcePalette = definition.Palette.Span; this.paletteOwner = this.Configuration.MemoryAllocator.Allocate <TPixel>(sourcePalette.Length); Color.ToPixel(this.Configuration, sourcePalette, this.paletteOwner.Memory.Span); this.ditherProcessor = new DitherProcessor( this.Configuration, this.paletteOwner.Memory, definition.DitherScale); }
public void CommonDitherers_WorkWithDiscoBuffers <TPixel>( TestImageProvider <TPixel> provider, string name) where TPixel : unmanaged, IPixel <TPixel> { IDither dither = TestUtils.GetDither(name); if (SkipAllDitherTests) { return; } provider.RunBufferCapacityLimitProcessorTest( 41, c => c.Dither(dither), name); }
public void DitherFilter_WorksWithAllDitherers <TPixel>( TestImageProvider <TPixel> provider, IDither ditherer, string name) where TPixel : struct, IPixel <TPixel> { if (SkipAllDitherTests) { return; } provider.RunValidatingProcessorTest( x => x.Dither(ditherer), testOutputDetails: name, comparer: ValidatorComparer, appendPixelTypeToFileName: false); }
public void CommonDitherers_WorkWithDiscoBuffers <TPixel>( TestImageProvider <TPixel> provider, string name) where TPixel : struct, IPixel <TPixel> { IDither dither = TestUtils.GetDither(name); if (SkipAllDitherTests) { return; } provider.RunBufferCapacityLimitProcessorTest( 41, c => c.Dither(dither), name, ImageComparer.TolerantPercentage(0.001f)); }
public static IDither CreateDither(DitherAlgorithm ditherAlgorithm) { Initialize(); IDither dither = null; var attribute = _enumLinks.Where(l => l.EnumValue == (int)ditherAlgorithm); if (attribute.Any()) { var foundAttribute = attribute.First(); dither = (IDither)Activator.CreateInstance(foundAttribute.Type); } else { throw new NotSupportedException(ditherAlgorithm.ToString() + " is not supported"); } return(dither); }
private static void SecondPass <TFrameQuantizer, TPixel>( ref TFrameQuantizer quantizer, ImageFrame <TPixel> source, Rectangle bounds, Memory <byte> output, ReadOnlyMemory <TPixel> palette) where TFrameQuantizer : struct, IFrameQuantizer <TPixel> where TPixel : unmanaged, IPixel <TPixel> { IDither dither = quantizer.Options.Dither; if (dither is null) { var operation = new RowIntervalOperation <TFrameQuantizer, TPixel>(quantizer, source, output, bounds, palette); ParallelRowIterator.IterateRowIntervals( quantizer.Configuration, bounds, in operation); return; } dither.ApplyQuantizationDither(ref quantizer, palette, source, output, bounds); }
/// <summary> /// Initializes a new instance of the <see cref="PaletteDitherProcessor"/> class. /// </summary> /// <param name="dither">The ordered ditherer.</param> /// <param name="ditherScale">The dithering scale used to adjust the amount of dither.</param> public PaletteDitherProcessor(IDither dither, float ditherScale) : this(dither, ditherScale, Color.WebSafePalette) { }
public bool TwoColor() { var Folder = Config.InputFolder; var files = Directory.EnumerateFiles(Folder, "*.png"); var filenames = files.ToArray(); MathUtils.NumericalSort(filenames); var contrast = Config.Contrast; IDither DitheringType = null; switch (Config.DitheringMode) { case 0: break; case 1: DitheringType = KnownDitherings.Bayer8x8; break; case 2: DitheringType = KnownDitherings.Bayer4x4; break; case 3: DitheringType = KnownDitherings.Bayer2x2; break; case 4: DitheringType = KnownDitherings.FloydSteinberg; break; case 5: DitheringType = KnownDitherings.Atkinson; break; case 6: DitheringType = KnownDitherings.Burks; break; case 7: DitheringType = KnownDitherings.JarvisJudiceNinke; break; case 8: DitheringType = KnownDitherings.StevensonArce; break; case 9: DitheringType = KnownDitherings.Sierra2; break; case 10: DitheringType = KnownDitherings.Sierra3; break; case 11: DitheringType = KnownDitherings.SierraLite; break; case 12: DitheringType = KnownDitherings.Stucki; break; case 13: DitheringType = KnownDitherings.Ordered3x3; break; default: //this one is my favorite :) DitheringType = KnownDitherings.Bayer8x8; break; } List <Color> colors = new List <Color>(); for (int i = 0; i < filenames.Length; i++) { using (Image <Rgba32> image = (Image <Rgba32>)Image.Load(filenames[i])) { image.Mutate(x => { if (contrast != 0) { x.Contrast(contrast); } if (DitheringType == null) { x.AdaptiveThreshold(); } else { x.BinaryDither(DitheringType); } }); image.SaveAsPng($"{Folder}/frame_{i}.png"); image.Dispose(); } } return(true); }
public bool FullColor() { var Folder = Config.InputFolder; var files = Directory.EnumerateFiles(Folder, "*.png"); var filenames = files.ToArray(); MathUtils.NumericalSort(filenames); var contrast = Config.Contrast; IDither DitheringType = null; switch (Config.DitheringMode) { case 1: DitheringType = KnownDitherings.Bayer8x8; break; case 2: DitheringType = KnownDitherings.Bayer4x4; break; case 3: DitheringType = KnownDitherings.Bayer2x2; break; case 4: DitheringType = KnownDitherings.FloydSteinberg; break; case 5: DitheringType = KnownDitherings.Atkinson; break; case 6: DitheringType = KnownDitherings.Burks; break; case 7: DitheringType = KnownDitherings.JarvisJudiceNinke; break; case 8: DitheringType = KnownDitherings.StevensonArce; break; case 9: DitheringType = KnownDitherings.Sierra2; break; case 10: DitheringType = KnownDitherings.Sierra3; break; case 11: DitheringType = KnownDitherings.SierraLite; break; case 12: DitheringType = KnownDitherings.Stucki; break; case 13: DitheringType = KnownDitherings.Ordered3x3; break; default: DitheringType = null; break; } List <Color> colors = new List <Color>(); colors.Add(Color.Red); colors.Add(Color.Black); colors.Add(Color.White); colors.Add(Color.Blue); if (DitheringType != null) { for (int i = 0; i < filenames.Length; i++) { Directory.CreateDirectory("tmp"); using (Image <Rgba32> image = (Image <Rgba32>)Image.Load(filenames[i])) { Image <Rgba32> bw = image.Clone(); bw.Mutate(x => { if (contrast != 0) { x.Contrast(contrast); } x.BinaryDither(DitheringType); }); bw.Save($"tmp/frame_{i}.png"); bw.Dispose(); image.Mutate(x => { if (contrast != 0) { x.Contrast(contrast); } //x.BinaryDither(DitheringType); var Palette = new ReadOnlyMemory <Color>(colors.ToArray()); x.Dither(DitheringType, Palette); }); image.SaveAsPng($"frames/frame_{i}.png"); image.Dispose(); } } } return(true); }
/// <summary> /// Dithers the image reducing it to two colors using ordered dithering. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="dither">The ordered ditherer.</param> /// <param name="rectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// </param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext BinaryDither( this IImageProcessingContext source, IDither dither, Rectangle rectangle) => BinaryDither(source, dither, Color.White, Color.Black, rectangle);
/// <summary> /// Dithers the image reducing it to a web-safe palette using ordered dithering. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="dither">The ordered ditherer.</param> /// <param name="ditherScale">The dithering scale used to adjust the amount of dither.</param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext Dither( this IImageProcessingContext source, IDither dither, float ditherScale) => source.ApplyProcessor(new PaletteDitherProcessor(dither, ditherScale));
/// <summary> /// Dithers the image reducing it to the given palette using ordered dithering. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="dither">The ordered ditherer.</param> /// <param name="palette">The palette to select substitute colors from.</param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext Dither( this IImageProcessingContext source, IDither dither, ReadOnlyMemory <Color> palette) => source.ApplyProcessor(new PaletteDitherProcessor(dither, palette));
BinaryDither(this IImageProcessingContext source, IDither dither) => BinaryDither(source, dither, Color.White, Color.Black);
public DitherTest() { this.orderedDither = KnownDitherings.Bayer4x4; this.errorDiffuser = KnownDitherings.FloydSteinberg; }
/// <summary> /// Dithers the image reducing it to a web-safe palette using ordered dithering. /// </summary> /// <param name="source">The image this method extends.</param> /// <param name="dither">The ordered ditherer.</param> /// <param name="rectangle"> /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// </param> /// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns> public static IImageProcessingContext Dither( this IImageProcessingContext source, IDither dither, Rectangle rectangle) => source.ApplyProcessor(new PaletteDitherProcessor(dither), rectangle);
public void BinaryDitherFilter_WorksWithAllDitherers <TPixel>(TestImageProvider <TPixel> provider, string name, IDither ditherer) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) { image.Mutate(x => x.BinaryDither(ditherer)); image.DebugSave(provider, name); } }
public void DiffusionFilter_WorksWithAllErrorDiffusers <TPixel>(TestImageProvider <TPixel> provider, string name, IDither diffuser) where TPixel : unmanaged, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) { image.Mutate(x => x.BinaryDither(diffuser)); image.DebugSave(provider, name); } }
/// <summary> /// Initializes a new instance of the <see cref="PaletteDitherProcessor"/> class. /// </summary> /// <param name="dither">The ordered ditherer.</param> public PaletteDitherProcessor(IDither dither) : this(dither, QuantizerConstants.MaxDitherScale) { }
/// <summary> /// Initializes a new instance of the <see cref="PaletteDitherProcessor"/> class. /// </summary> /// <param name="dither">The dithering algorithm.</param> /// <param name="palette">The palette to select substitute colors from.</param> public PaletteDitherProcessor(IDither dither, ReadOnlyMemory <Color> palette) : this(dither, QuantizerConstants.MaxDitherScale, palette) { }
/// <inheritdoc/> public bool Equals(IDither other) => this.Equals((object)other);