Browse Source
Merge pull request #452 from SixLabors/js/fix-semi-opaque-dithering
Fix and optimize error diffusion
pull/455/head
James Jackson-South
8 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with
20 additions and
10 deletions
-
src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuserBase.cs
-
src/ImageSharp/Formats/Png/PngEncoder.cs
-
src/ImageSharp/Formats/Png/PngEncoderCore.cs
-
src/ImageSharp/Quantizers/QuantizerBase{TPixel}.cs
-
src/ImageSharp/Quantizers/WuQuantizer{TPixel}.cs
-
tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs
|
|
|
@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Dithering.Base |
|
|
|
this.startingOffset = 0; |
|
|
|
for (int i = 0; i < this.matrixWidth; i++) |
|
|
|
{ |
|
|
|
// Good to disable here as we are not comparing matematical output.
|
|
|
|
// Good to disable here as we are not comparing mathematical output.
|
|
|
|
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
|
|
|
if (matrix[0, i] != 0) |
|
|
|
{ |
|
|
|
@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Dithering.Base |
|
|
|
// Calculate the error
|
|
|
|
Vector4 error = source.ToVector4() - transformed.ToVector4(); |
|
|
|
|
|
|
|
// Loop through and distribute the error amongst neighbouring pixels.
|
|
|
|
// Loop through and distribute the error amongst neighboring pixels.
|
|
|
|
for (int row = 0; row < this.matrixHeight; row++) |
|
|
|
{ |
|
|
|
int matrixY = y + row; |
|
|
|
@ -115,10 +115,8 @@ namespace SixLabors.ImageSharp.Dithering.Base |
|
|
|
|
|
|
|
ref TPixel pixel = ref rowSpan[matrixX]; |
|
|
|
var offsetColor = pixel.ToVector4(); |
|
|
|
var coefficientVector = new Vector4(coefficient); |
|
|
|
|
|
|
|
Vector4 result = ((error * coefficientVector) / this.divisorVector) + offsetColor; |
|
|
|
result.W = offsetColor.W; |
|
|
|
Vector4 result = ((error * coefficient) / this.divisorVector) + offsetColor; |
|
|
|
pixel.PackFromVector4(result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
|
public bool IgnoreMetadata { get; set; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the size of the color palette to use. Set to zero to leav png encoding to use pixel data.
|
|
|
|
/// Gets or sets the size of the color palette to use. Set to zero to leave png encoding to use pixel data.
|
|
|
|
/// </summary>
|
|
|
|
public int PaletteSize { get; set; } = 0; |
|
|
|
|
|
|
|
|
|
|
|
@ -148,7 +148,7 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="PngEncoderCore"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="options">The options for influancing the encoder</param>
|
|
|
|
/// <param name="options">The options for influencing the encoder</param>
|
|
|
|
public PngEncoderCore(IPngEncoderOptions options) |
|
|
|
{ |
|
|
|
this.ignoreMetadata = options.IgnoreMetadata; |
|
|
|
|
|
|
|
@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Quantizers.Base |
|
|
|
} |
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public bool Dither { get; set; } = false; |
|
|
|
public bool Dither { get; set; } = true; |
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public IErrorDiffuser DitherType { get; set; } = new FloydSteinbergDiffuser(); |
|
|
|
|
|
|
|
@ -281,7 +281,7 @@ namespace SixLabors.ImageSharp.Quantizers |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the index index of the given color in the palette.
|
|
|
|
/// Gets the index of the given color in the palette.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="r">The red value.</param>
|
|
|
|
/// <param name="g">The green value.</param>
|
|
|
|
@ -827,7 +827,7 @@ namespace SixLabors.ImageSharp.Quantizers |
|
|
|
{ |
|
|
|
if (this.Dither) |
|
|
|
{ |
|
|
|
// The colors have changed so we need to use Euclidean distance caclulation to find the closest value.
|
|
|
|
// The colors have changed so we need to use Euclidean distance calculation to find the closest value.
|
|
|
|
// This palette can never be null here.
|
|
|
|
return this.GetClosestPixel(pixel, this.palette, this.colorMap); |
|
|
|
} |
|
|
|
|
|
|
|
@ -7,6 +7,18 @@ |
|
|
|
|
|
|
|
public class QuantizedImageTests |
|
|
|
{ |
|
|
|
[Fact] |
|
|
|
public void QuantizersDitherByDefault() |
|
|
|
{ |
|
|
|
var palette = new PaletteQuantizer<Rgba32>(); |
|
|
|
var octree = new OctreeQuantizer<Rgba32>(); |
|
|
|
var wu = new WuQuantizer<Rgba32>(); |
|
|
|
|
|
|
|
Assert.True(palette.Dither); |
|
|
|
Assert.True(octree.Dither); |
|
|
|
Assert.True(wu.Dither); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, true)] |
|
|
|
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, false)] |
|
|
|
|