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

Loading…
Cancel
Save