diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 02bb67c728..12a681feab 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/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 quantized = PngEncoderOptionsHelpers.CreateQuantizedFrame(this.options, image); - this.bitDepth = PngEncoderOptionsHelpers.CalculateBitDepth(this.options, image, quantized); + + IQuantizedFrame quantized; + + if (((this.options.OptimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.MakeTransparentBlack) == PngOptimizeMethod.MakeTransparentBlack) + { + using (Image tempImage = image.Clone()) + { + Span 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 /// The pixel format. /// The containing image data. /// The quantized frame. - /// The optimize method. - private void WritePaletteChunk(Stream stream, IQuantizedFrame quantized, PngOptimizeMethod? optimizeMethod) + private void WritePaletteChunk(Stream stream, IQuantizedFrame quantized) where TPixel : struct, IPixel { 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) {