Browse Source

Update: transparent pixels to black before quantization

pull/1574/head
Peter Tribe 7 years ago
parent
commit
63fb07c8b2
  1. 56
      src/ImageSharp/Formats/Png/PngEncoderCore.cs

56
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -147,13 +147,43 @@ namespace SixLabors.ImageSharp.Formats.Png
ImageMetadata metadata = image.Metadata;
PngMetadata pngMetadata = metadata.GetFormatMetadata(PngFormat.Instance);
PngEncoderOptionsHelpers.AdjustOptions(this.options, pngMetadata, out this.use16Bit, out this.bytesPerPixel);
IQuantizedFrame<TPixel> quantized = PngEncoderOptionsHelpers.CreateQuantizedFrame(this.options, image);
this.bitDepth = PngEncoderOptionsHelpers.CalculateBitDepth(this.options, image, quantized);
IQuantizedFrame<TPixel> quantized;
if (((this.options.OptimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.MakeTransparentBlack) == PngOptimizeMethod.MakeTransparentBlack)
{
using (Image<TPixel> tempImage = image.Clone())
{
Span<TPixel> span = tempImage.GetPixelSpan();
foreach (TPixel pixel in span)
{
Rgba32 rgba32 = Rgba32.Transparent;
pixel.ToRgba32(ref rgba32);
if (rgba32.A == 0)
{
rgba32.R = 0;
rgba32.G = 0;
rgba32.B = 0;
}
pixel.FromRgba32(rgba32);
}
quantized = PngEncoderOptionsHelpers.CreateQuantizedFrame(this.options, tempImage);
this.bitDepth = PngEncoderOptionsHelpers.CalculateBitDepth(this.options, tempImage, quantized);
}
}
else
{
quantized = PngEncoderOptionsHelpers.CreateQuantizedFrame(this.options, image);
this.bitDepth = PngEncoderOptionsHelpers.CalculateBitDepth(this.options, image, quantized);
}
stream.Write(PngConstants.HeaderBytes, 0, PngConstants.HeaderBytes.Length);
this.WriteHeaderChunk(stream);
this.WritePaletteChunk(stream, quantized, this.options.OptimizeMethod);
this.WritePaletteChunk(stream, quantized);
this.WriteTransparencyChunk(stream, pngMetadata);
if (((this.options.OptimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.SuppressPhysicalChunk) != PngOptimizeMethod.SuppressPhysicalChunk)
@ -564,8 +594,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
/// <param name="quantized">The quantized frame.</param>
/// <param name="optimizeMethod">The optimize method.</param>
private void WritePaletteChunk<TPixel>(Stream stream, IQuantizedFrame<TPixel> quantized, PngOptimizeMethod? optimizeMethod)
private void WritePaletteChunk<TPixel>(Stream stream, IQuantizedFrame<TPixel> quantized)
where TPixel : struct, IPixel<TPixel>
{
if (quantized == null)
@ -588,8 +617,6 @@ namespace SixLabors.ImageSharp.Formats.Png
Rgba32 rgba = default;
bool makeTransparentBlack = ((optimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.MakeTransparentBlack) == PngOptimizeMethod.MakeTransparentBlack;
for (int i = 0; i < paletteLength; i++)
{
if (quantizedSpan.IndexOf((byte)i) > -1)
@ -599,18 +626,9 @@ namespace SixLabors.ImageSharp.Formats.Png
byte alpha = rgba.A;
if (makeTransparentBlack && alpha == 0)
{
Unsafe.Add(ref colorTableRef, offset) = 0;
Unsafe.Add(ref colorTableRef, offset + 1) = 0;
Unsafe.Add(ref colorTableRef, offset + 2) = 0;
}
else
{
Unsafe.Add(ref colorTableRef, offset) = rgba.R;
Unsafe.Add(ref colorTableRef, offset + 1) = rgba.G;
Unsafe.Add(ref colorTableRef, offset + 2) = rgba.B;
}
Unsafe.Add(ref colorTableRef, offset) = rgba.R;
Unsafe.Add(ref colorTableRef, offset + 1) = rgba.G;
Unsafe.Add(ref colorTableRef, offset + 2) = rgba.B;
if (alpha > this.options.Threshold)
{

Loading…
Cancel
Save