diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoder.cs b/src/ImageSharp/Formats/Bmp/BmpEncoder.cs
index f3eb9282c..612675c33 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoder.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoder.cs
@@ -4,6 +4,7 @@
using System.IO;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing.Processors.Quantization;
namespace SixLabors.ImageSharp.Formats.Bmp
{
@@ -25,6 +26,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
public bool SupportTransparency { get; set; }
+ ///
+ /// Gets or sets the quantizer for reducing the color count for 8-Bit images.
+ /// Defaults to OctreeQuantizer.
+ ///
+ public IQuantizer Quantizer { get; set; }
+
///
public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
index 8d0e8578d..90ea673d3 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using System.Buffers;
using System.IO;
using SixLabors.ImageSharp.Advanced;
@@ -62,6 +63,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
private readonly bool writeV4Header;
+ ///
+ /// The quantizer for reducing the color count for 8-Bit images.
+ ///
+ private readonly IQuantizer quantizer;
+
///
/// Initializes a new instance of the class.
///
@@ -72,6 +78,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
this.memoryAllocator = memoryAllocator;
this.bitsPerPixel = options.BitsPerPixel;
this.writeV4Header = options.SupportTransparency;
+ this.quantizer = options.Quantizer ?? new OctreeQuantizer(dither: true, maxColors: 256);
}
///
@@ -298,39 +305,35 @@ namespace SixLabors.ImageSharp.Formats.Bmp
private void Write8Bit(Stream stream, ImageFrame image)
where TPixel : struct, IPixel
{
-#if NETCOREAPP2_1
- Span colorPalette = stackalloc byte[ColorPaletteSize8Bit];
-#else
- byte[] colorPalette = new byte[ColorPaletteSize8Bit];
-#endif
-
- var quantizer = new OctreeQuantizer(dither: true, maxColors: 256);
- QuantizedFrame quantized = quantizer.CreateFrameQuantizer(this.configuration).QuantizeFrame(image);
-
- int idx = 0;
- var color = default(Rgba32);
- foreach (TPixel quantizedColor in quantized.Palette)
+ using (IMemoryOwner colorPaletteBuffer = this.memoryAllocator.AllocateManagedByteBuffer(ColorPaletteSize8Bit, AllocationOptions.Clean))
+ using (QuantizedFrame quantized = this.quantizer.CreateFrameQuantizer(this.configuration, 256).QuantizeFrame(image))
{
- quantizedColor.ToRgba32(ref color);
- colorPalette[idx] = color.B;
- colorPalette[idx + 1] = color.G;
- colorPalette[idx + 2] = color.R;
-
- // Padding byte, always 0
- colorPalette[idx + 3] = 0;
- idx += 4;
- }
-
- stream.Write(colorPalette, 0, ColorPaletteSize8Bit);
+ Span colorPalette = colorPaletteBuffer.GetSpan();
+ int idx = 0;
+ var color = default(Rgba32);
+ foreach (TPixel quantizedColor in quantized.Palette)
+ {
+ quantizedColor.ToRgba32(ref color);
+ colorPalette[idx] = color.B;
+ colorPalette[idx + 1] = color.G;
+ colorPalette[idx + 2] = color.R;
+
+ // Padding byte, always 0
+ colorPalette[idx + 3] = 0;
+ idx += 4;
+ }
- for (int y = image.Height - 1; y >= 0; y--)
- {
- Span pixelSpan = quantized.GetRowSpan(y);
- stream.Write(pixelSpan);
+ stream.Write(colorPalette);
- for (int i = 0; i < this.padding; i++)
+ for (int y = image.Height - 1; y >= 0; y--)
{
- stream.WriteByte(0);
+ Span pixelSpan = quantized.GetRowSpan(y);
+ stream.Write(pixelSpan);
+
+ for (int i = 0; i < this.padding; i++)
+ {
+ stream.WriteByte(0);
+ }
}
}
}
diff --git a/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs b/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs
index 92ff09270..59ad929df 100644
--- a/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs
+++ b/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs
@@ -1,10 +1,12 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+using SixLabors.ImageSharp.Processing.Processors.Quantization;
+
namespace SixLabors.ImageSharp.Formats.Bmp
{
///
- /// Configuration options for use during bmp encoding
+ /// Configuration options for use during bmp encoding.
///
internal interface IBmpEncoderOptions
{
@@ -20,5 +22,10 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Instead a bitmap version 4 info header will be written with the BITFIELDS compression.
///
bool SupportTransparency { get; }
+
+ ///
+ /// Gets the quantizer for reducing the color count for 8-Bit images.
+ ///
+ IQuantizer Quantizer { get; }
}
}
\ No newline at end of file