mirror of https://github.com/SixLabors/ImageSharp
4 changed files with 70 additions and 42 deletions
@ -1,59 +1,34 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
// Copyright (c) Six Labors and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
using System; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
using SixLabors.ImageSharp.PixelFormats; |
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Enables the quantization of images to reduce the number of colors used in the image palette.
|
/// Defines quantization processing for images to reduce the number of colors used in the image palette.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
public class QuantizeProcessor : IImageProcessor |
||||
internal class QuantizeProcessor<TPixel> : ImageProcessor<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="QuantizeProcessor{TPixel}"/> class.
|
/// Initializes a new instance of the <see cref="QuantizeProcessor"/> class.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="quantizer">The quantizer used to reduce the color palette</param>
|
/// <param name="quantizer">The quantizer used to reduce the color palette.</param>
|
||||
public QuantizeProcessor(IQuantizer quantizer) |
public QuantizeProcessor(IQuantizer quantizer) |
||||
{ |
{ |
||||
Guard.NotNull(quantizer, nameof(quantizer)); |
|
||||
this.Quantizer = quantizer; |
this.Quantizer = quantizer; |
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets the quantizer
|
/// Gets the quantizer.
|
||||
/// </summary>
|
/// </summary>
|
||||
public IQuantizer Quantizer { get; } |
public IQuantizer Quantizer { get; } |
||||
|
|
||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>() |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
{ |
{ |
||||
using (IFrameQuantizer<TPixel> executor = this.Quantizer.CreateFrameQuantizer<TPixel>(configuration)) |
return new QuantizeProcessor<TPixel>(this.Quantizer); |
||||
using (QuantizedFrame<TPixel> quantized = executor.QuantizeFrame(source)) |
|
||||
{ |
|
||||
int paletteCount = quantized.Palette.Length - 1; |
|
||||
|
|
||||
// Not parallel to remove "quantized" closure allocation.
|
|
||||
// We can operate directly on the source here as we've already read it to get the
|
|
||||
// quantized result
|
|
||||
for (int y = 0; y < source.Height; y++) |
|
||||
{ |
|
||||
Span<TPixel> row = source.GetPixelRowSpan(y); |
|
||||
ReadOnlySpan<byte> quantizedPixelSpan = quantized.GetPixelSpan(); |
|
||||
int yy = y * source.Width; |
|
||||
|
|
||||
for (int x = 0; x < source.Width; x++) |
|
||||
{ |
|
||||
int i = x + yy; |
|
||||
row[x] = quantized.Palette[Math.Min(paletteCount, quantizedPixelSpan[i])]; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
using SixLabors.ImageSharp.Advanced; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.Primitives; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Enables the quantization of images to reduce the number of colors used in the image palette.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
internal class QuantizeProcessor<TPixel> : ImageProcessor<TPixel> |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
private readonly IQuantizer quantizer; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="QuantizeProcessor{TPixel}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="quantizer">The quantizer used to reduce the color palette.</param>
|
||||
|
public QuantizeProcessor(IQuantizer quantizer) |
||||
|
{ |
||||
|
Guard.NotNull(quantizer, nameof(quantizer)); |
||||
|
this.quantizer = quantizer; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
||||
|
{ |
||||
|
using (IFrameQuantizer<TPixel> executor = this.quantizer.CreateFrameQuantizer<TPixel>(configuration)) |
||||
|
using (QuantizedFrame<TPixel> quantized = executor.QuantizeFrame(source)) |
||||
|
{ |
||||
|
int paletteCount = quantized.Palette.Length - 1; |
||||
|
|
||||
|
// Not parallel to remove "quantized" closure allocation.
|
||||
|
// We can operate directly on the source here as we've already read it to get the
|
||||
|
// quantized result
|
||||
|
for (int y = 0; y < source.Height; y++) |
||||
|
{ |
||||
|
Span<TPixel> row = source.GetPixelRowSpan(y); |
||||
|
ReadOnlySpan<byte> quantizedPixelSpan = quantized.GetPixelSpan(); |
||||
|
int yy = y * source.Width; |
||||
|
|
||||
|
for (int x = 0; x < source.Width; x++) |
||||
|
{ |
||||
|
int i = x + yy; |
||||
|
row[x] = quantized.Palette[Math.Min(paletteCount, quantizedPixelSpan[i])]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue