mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
110 changed files with 948 additions and 836 deletions
@ -1,56 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Quantization |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Represents a box color cube.
|
|
||||
/// </summary>
|
|
||||
internal struct Box |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets or sets the min red value, exclusive.
|
|
||||
/// </summary>
|
|
||||
public int R0 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the max red value, inclusive.
|
|
||||
/// </summary>
|
|
||||
public int R1 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the min green value, exclusive.
|
|
||||
/// </summary>
|
|
||||
public int G0 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the max green value, inclusive.
|
|
||||
/// </summary>
|
|
||||
public int G1 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the min blue value, exclusive.
|
|
||||
/// </summary>
|
|
||||
public int B0 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the max blue value, inclusive.
|
|
||||
/// </summary>
|
|
||||
public int B1 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the min alpha value, exclusive.
|
|
||||
/// </summary>
|
|
||||
public int A0 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the max alpha value, inclusive.
|
|
||||
/// </summary>
|
|
||||
public int A1 { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the volume.
|
|
||||
/// </summary>
|
|
||||
public int Volume { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,35 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering.ErrorDiffusion; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides methods to allow the execution of the quantization process on an image frame.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
public interface IFrameQuantizer<TPixel> |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets a value indicating whether to apply dithering to the output image.
|
||||
|
/// </summary>
|
||||
|
bool Dither { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the error diffusion algorithm to apply to the output image.
|
||||
|
/// </summary>
|
||||
|
IErrorDiffuser Diffuser { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Quantize an image frame and return the resulting output pixels.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">The image to quantize.</param>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="QuantizedFrame{TPixel}"/> representing a quantized version of the image pixels.
|
||||
|
/// </returns>
|
||||
|
QuantizedFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> image); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering.ErrorDiffusion; |
||||
|
using SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Quantization |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides methods for allowing quantization of images pixels with configurable dithering.
|
||||
|
/// </summary>
|
||||
|
public interface IQuantizer |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the error diffusion algorithm to apply to the output image.
|
||||
|
/// </summary>
|
||||
|
IErrorDiffuser Diffuser { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates the generic frame quantizer
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
/// <returns>The <see cref="IFrameQuantizer{TPixel}"/></returns>
|
||||
|
IFrameQuantizer<TPixel> CreateFrameQuantizer<TPixel>() |
||||
|
where TPixel : struct, IPixel<TPixel>; |
||||
|
} |
||||
|
} |
||||
@ -1,42 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Processing.Dithering.ErrorDiffusion; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Quantization |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides methods for for allowing quantization of images pixels with configurable dithering.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
public interface IQuantizer<TPixel> : IQuantizer |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Quantize an image and return the resulting output pixels.
|
|
||||
/// </summary>
|
|
||||
/// <param name="image">The image to quantize.</param>
|
|
||||
/// <param name="maxColors">The maximum number of colors to return.</param>
|
|
||||
/// <returns>
|
|
||||
/// A <see cref="T:QuantizedImage"/> representing a quantized version of the image pixels.
|
|
||||
/// </returns>
|
|
||||
QuantizedFrame<TPixel> Quantize(ImageFrame<TPixel> image, int maxColors); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Provides methods for allowing quantization of images pixels with configurable dithering.
|
|
||||
/// </summary>
|
|
||||
public interface IQuantizer |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating whether to apply dithering to the output image.
|
|
||||
/// </summary>
|
|
||||
bool Dither { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the dithering algorithm to apply to the output image.
|
|
||||
/// </summary>
|
|
||||
IErrorDiffuser DitherType { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,29 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Quantization |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Contains reusable static instances of known quantizing algorithms
|
||||
|
/// </summary>
|
||||
|
public static class KnownQuantizers |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the adaptive Octree quantizer. Fast with good quality.
|
||||
|
/// The quantizer only supports a single alpha value.
|
||||
|
/// </summary>
|
||||
|
public static IQuantizer Octree { get; } = new OctreeQuantizer(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the Xiaolin Wu's Color Quantizer which generates high quality output.
|
||||
|
/// The quantizer supports multiple alpha values.
|
||||
|
/// </summary>
|
||||
|
public static IQuantizer Wu { get; } = new WuQuantizer(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the palette based, Using the collection of web-safe colors.
|
||||
|
/// The quantizer supports multiple alpha values.
|
||||
|
/// </summary>
|
||||
|
public static IQuantizer Palette { get; } = new PaletteQuantizer(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,83 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering.ErrorDiffusion; |
||||
|
using SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Quantization |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Allows the quantization of images pixels using Octrees.
|
||||
|
/// <see href="http://msdn.microsoft.com/en-us/library/aa479306.aspx"/>
|
||||
|
/// <para>
|
||||
|
/// By default the quantizer uses <see cref="KnownDiffusers.FloydSteinberg"/> dithering and a color palette of a maximum length of <value>255</value>
|
||||
|
/// </para>
|
||||
|
/// </summary>
|
||||
|
public class OctreeQuantizer : IQuantizer |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="OctreeQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
public OctreeQuantizer() |
||||
|
: this(true) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="OctreeQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="maxColors">The maximum number of colors to hold in the color palette</param>
|
||||
|
public OctreeQuantizer(int maxColors) |
||||
|
: this(GetDiffuser(true), maxColors) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="OctreeQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="dither">Whether to apply dithering to the output image</param>
|
||||
|
public OctreeQuantizer(bool dither) |
||||
|
: this(GetDiffuser(dither), 255) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="OctreeQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="diffuser">The error diffusion algorithm, if any, to apply to the output image</param>
|
||||
|
public OctreeQuantizer(IErrorDiffuser diffuser) |
||||
|
: this(diffuser, 255) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="OctreeQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="diffuser">The error diffusion algorithm, if any, to apply to the output image</param>
|
||||
|
/// <param name="maxColors">The maximum number of colors to hold in the color palette</param>
|
||||
|
public OctreeQuantizer(IErrorDiffuser diffuser, int maxColors) |
||||
|
{ |
||||
|
Guard.MustBeBetweenOrEqualTo(maxColors, 1, 255, nameof(maxColors)); |
||||
|
|
||||
|
this.Diffuser = diffuser; |
||||
|
this.MaxColors = maxColors; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public IErrorDiffuser Diffuser { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the maximum number of colors to hold in the color palette.
|
||||
|
/// </summary>
|
||||
|
public int MaxColors { get; } |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public IFrameQuantizer<TPixel> CreateFrameQuantizer<TPixel>() |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
=> new OctreeFrameQuantizer<TPixel>(this); |
||||
|
|
||||
|
private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering.ErrorDiffusion; |
||||
|
using SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Quantization |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Allows the quantization of images pixels using web safe colors defined in the CSS Color Module Level 4.
|
||||
|
/// <see href="http://msdn.microsoft.com/en-us/library/aa479306.aspx"/> Override this class to provide your own palette.
|
||||
|
/// <para>
|
||||
|
/// By default the quantizer uses <see cref="KnownDiffusers.FloydSteinberg"/> dithering and the <see cref="NamedColors{TPixel}.WebSafePalette"/>
|
||||
|
/// </para>
|
||||
|
/// </summary>
|
||||
|
public class PaletteQuantizer : IQuantizer |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PaletteQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
public PaletteQuantizer() |
||||
|
: this(true) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PaletteQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="dither">Whether to apply dithering to the output image</param>
|
||||
|
public PaletteQuantizer(bool dither) |
||||
|
: this(GetDiffuser(dither)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PaletteQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="diffuser">The error diffusion algorithm, if any, to apply to the output image</param>
|
||||
|
public PaletteQuantizer(IErrorDiffuser diffuser) |
||||
|
{ |
||||
|
this.Diffuser = diffuser; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public IErrorDiffuser Diffuser { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the palette to use to quantize the image.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
/// <returns>The <see cref="T:TPixel[]"/></returns>
|
||||
|
public virtual TPixel[] GetPalette<TPixel>() |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
=> NamedColors<TPixel>.WebSafePalette; |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public IFrameQuantizer<TPixel> CreateFrameQuantizer<TPixel>() |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
=> new PaletteFrameQuantizer<TPixel>(this); |
||||
|
|
||||
|
private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null; |
||||
|
} |
||||
|
} |
||||
@ -1,29 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Quantization |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides enumeration over how an image should be quantized.
|
|
||||
/// </summary>
|
|
||||
public enum QuantizationMode |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// An adaptive Octree quantizer. Fast with good quality.
|
|
||||
/// The quantizer only supports a single alpha value.
|
|
||||
/// </summary>
|
|
||||
Octree, |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Xiaolin Wu's Color Quantizer which generates high quality output.
|
|
||||
/// The quantizer supports multiple alpha values.
|
|
||||
/// </summary>
|
|
||||
Wu, |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Palette based, Uses the collection of web-safe colors by default.
|
|
||||
/// The quantizer supports multiple alpha values.
|
|
||||
/// </summary>
|
|
||||
Palette |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,82 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering; |
||||
|
using SixLabors.ImageSharp.Processing.Dithering.ErrorDiffusion; |
||||
|
using SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Quantization |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Allows the quantization of images pixels using Xiaolin Wu's Color Quantizer <see href="http://www.ece.mcmaster.ca/~xwu/cq.c"/>
|
||||
|
/// <para>
|
||||
|
/// By default the quantizer uses <see cref="KnownDiffusers.FloydSteinberg"/> dithering and a color palette of a maximum length of <value>255</value>
|
||||
|
/// </para>
|
||||
|
/// </summary>
|
||||
|
public class WuQuantizer : IQuantizer |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="WuQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
public WuQuantizer() |
||||
|
: this(true) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="WuQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="maxColors">The maximum number of colors to hold in the color palette</param>
|
||||
|
public WuQuantizer(int maxColors) |
||||
|
: this(GetDiffuser(true), maxColors) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="WuQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="dither">Whether to apply dithering to the output image</param>
|
||||
|
public WuQuantizer(bool dither) |
||||
|
: this(GetDiffuser(dither), 255) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="WuQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="diffuser">The error diffusion algorithm, if any, to apply to the output image</param>
|
||||
|
public WuQuantizer(IErrorDiffuser diffuser) |
||||
|
: this(diffuser, 255) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="WuQuantizer"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="diffuser">The error diffusion algorithm, if any, to apply to the output image</param>
|
||||
|
/// <param name="maxColors">The maximum number of colors to hold in the color palette</param>
|
||||
|
public WuQuantizer(IErrorDiffuser diffuser, int maxColors) |
||||
|
{ |
||||
|
Guard.MustBeBetweenOrEqualTo(maxColors, 1, 255, nameof(maxColors)); |
||||
|
|
||||
|
this.Diffuser = diffuser; |
||||
|
this.MaxColors = maxColors; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public IErrorDiffuser Diffuser { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the maximum number of colors to hold in the color palette.
|
||||
|
/// </summary>
|
||||
|
public int MaxColors { get; } |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public IFrameQuantizer<TPixel> CreateFrameQuantizer<TPixel>() |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
=> new WuFrameQuantizer<TPixel>(this); |
||||
|
|
||||
|
private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null; |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue