diff --git a/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs b/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs
index 770afa3c5..ca9d5757f 100644
--- a/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs
+++ b/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs
@@ -70,8 +70,9 @@ namespace SixLabors.ImageSharp.Formats.Png
PngChunkFilter? ChunkFilter { get; }
///
- /// Gets a value indicating whether fully transparent pixels should be converted to black pixels.
+ /// Gets a value indicating whether fully transparent pixels that may contain R, G, B values which are not 0,
+ /// should be converted to transparent black, which can yield in better compression in some cases.
///
- bool MakeTransparentBlack { get; }
+ PngTransparentColorBehavior TransparentColorBehavior { get; }
}
}
diff --git a/src/ImageSharp/Formats/Png/PngEncoder.cs b/src/ImageSharp/Formats/Png/PngEncoder.cs
index 062e56c1d..d4ca4b7df 100644
--- a/src/ImageSharp/Formats/Png/PngEncoder.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoder.cs
@@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Png
public bool IgnoreMetadata { get; set; }
///
- public bool MakeTransparentBlack { get; set; }
+ public PngTransparentColorBehavior TransparentColorBehavior { get; set; }
///
/// Encodes the image to the specified stream from the .
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index 12ffb2cfc..05c17f376 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -145,10 +145,11 @@ namespace SixLabors.ImageSharp.Formats.Png
PngMetadata pngMetadata = metadata.GetFormatMetadata(PngFormat.Instance);
PngEncoderOptionsHelpers.AdjustOptions(this.options, pngMetadata, out this.use16Bit, out this.bytesPerPixel);
Image clonedImage = null;
- if (this.options.MakeTransparentBlack)
+ bool clearTransparency = this.options.TransparentColorBehavior == PngTransparentColorBehavior.Clear;
+ if (clearTransparency)
{
clonedImage = image.Clone();
- MakeTransparentPixelsBlack(clonedImage);
+ ClearTransparentPixels(clonedImage);
}
IndexedImageFrame quantized = this.CreateQuantizedImage(image, clonedImage);
@@ -162,7 +163,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.WritePhysicalChunk(stream, metadata);
this.WriteExifChunk(stream, metadata);
this.WriteTextChunks(stream, pngMetadata);
- this.WriteDataChunks(this.options.MakeTransparentBlack ? clonedImage : image, quantized, stream);
+ this.WriteDataChunks(clearTransparency ? clonedImage : image, quantized, stream);
this.WriteEndChunk(stream);
stream.Flush();
@@ -190,11 +191,11 @@ namespace SixLabors.ImageSharp.Formats.Png
}
///
- /// Makes transparent pixels black.
+ /// Convert transparent pixels, to transparent black pixels, which can yield to better compression in some cases.
///
/// The type of the pixel.
/// The cloned image where the transparent pixels will be changed.
- private static void MakeTransparentPixelsBlack(Image image)
+ private static void ClearTransparentPixels(Image image)
where TPixel : unmanaged, IPixel
{
Rgba32 rgba32 = default;
@@ -207,7 +208,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (rgba32.A == 0)
{
- span[x].FromRgba32(Color.Black);
+ span[x].FromRgba32(Color.Transparent);
}
}
}
@@ -224,7 +225,7 @@ namespace SixLabors.ImageSharp.Formats.Png
where TPixel : unmanaged, IPixel
{
IndexedImageFrame quantized;
- if (this.options.MakeTransparentBlack)
+ if (this.options.TransparentColorBehavior == PngTransparentColorBehavior.Clear)
{
quantized = PngEncoderOptionsHelpers.CreateQuantizedFrame(this.options, clonedImage);
this.bitDepth = PngEncoderOptionsHelpers.CalculateBitDepth(this.options, quantized);
diff --git a/src/ImageSharp/Formats/Png/PngEncoderOptions.cs b/src/ImageSharp/Formats/Png/PngEncoderOptions.cs
index d0eb1a843..e46dafada 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderOptions.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderOptions.cs
@@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.InterlaceMethod = source.InterlaceMethod;
this.ChunkFilter = source.ChunkFilter;
this.IgnoreMetadata = source.IgnoreMetadata;
- this.MakeTransparentBlack = source.MakeTransparentBlack;
+ this.TransparentColorBehavior = source.TransparentColorBehavior;
}
///
@@ -68,6 +68,6 @@ namespace SixLabors.ImageSharp.Formats.Png
public bool IgnoreMetadata { get; set; }
///
- public bool MakeTransparentBlack { get; set; }
+ public PngTransparentColorBehavior TransparentColorBehavior { get; set; }
}
}
diff --git a/src/ImageSharp/Formats/Png/PngTransparentColorBehavior.cs b/src/ImageSharp/Formats/Png/PngTransparentColorBehavior.cs
new file mode 100644
index 000000000..b459751c4
--- /dev/null
+++ b/src/ImageSharp/Formats/Png/PngTransparentColorBehavior.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the GNU Affero General Public License, Version 3.
+
+namespace SixLabors.ImageSharp.Formats.Png
+{
+ ///
+ /// Enum indicating how the transparency should be handled on encoding.
+ ///
+ public enum PngTransparentColorBehavior
+ {
+ ///
+ /// Converts fully transparent pixels that may contain R, G, B values which are not 0,
+ /// to transparent black, which can yield in better compression in some cases.
+ ///
+ Clear,
+
+ ///
+ /// The transparency will be kept as is.
+ ///
+ Preserve
+ }
+}
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
index 857445260..d29279b29 100644
--- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
@@ -392,17 +392,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
[Theory]
[InlineData(PngColorType.Palette)]
- [InlineData(PngColorType.Rgb)]
[InlineData(PngColorType.RgbWithAlpha)]
- [InlineData(PngColorType.Grayscale)]
[InlineData(PngColorType.GrayscaleWithAlpha)]
- public void Encode_WithMakeTransparentBlackOption_Works(PngColorType colorType)
+ public void Encode_WithPngTransparentColorBehaviorClear_Works(PngColorType colorType)
{
// arrange
var image = new Image(50, 50);
var encoder = new PngEncoder()
{
- MakeTransparentBlack = true,
+ TransparentColorBehavior = PngTransparentColorBehavior.Clear,
ColorType = colorType
};
Rgba32 rgba32 = Color.Blue;
@@ -442,7 +440,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
if (y > 25)
{
- expectedColor = Color.Black;
+ expectedColor = Color.Transparent;
}
for (int x = 0; x < actual.Width; x++)