diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 024bd6221..87c22a2ad 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -656,8 +656,8 @@ namespace SixLabors.ImageSharp.Formats.Png
scanlineSpan,
rowSpan,
pngMetaData.HasTrans,
- pngMetaData.Luminance16Trans,
- pngMetaData.LuminanceTrans);
+ pngMetaData.Luminance16Trans.GetValueOrDefault(),
+ pngMetaData.LuminanceTrans.GetValueOrDefault());
break;
@@ -690,8 +690,8 @@ namespace SixLabors.ImageSharp.Formats.Png
this.bytesPerPixel,
this.bytesPerSample,
pngMetaData.HasTrans,
- pngMetaData.Rgb48Trans,
- pngMetaData.Rgb24Trans);
+ pngMetaData.Rgb48Trans.GetValueOrDefault(),
+ pngMetaData.Rgb24Trans.GetValueOrDefault());
break;
@@ -740,8 +740,8 @@ namespace SixLabors.ImageSharp.Formats.Png
pixelOffset,
increment,
pngMetaData.HasTrans,
- pngMetaData.Luminance16Trans,
- pngMetaData.LuminanceTrans);
+ pngMetaData.Luminance16Trans.GetValueOrDefault(),
+ pngMetaData.LuminanceTrans.GetValueOrDefault());
break;
@@ -779,8 +779,8 @@ namespace SixLabors.ImageSharp.Formats.Png
this.bytesPerPixel,
this.bytesPerSample,
pngMetaData.HasTrans,
- pngMetaData.Rgb48Trans,
- pngMetaData.Rgb24Trans);
+ pngMetaData.Rgb48Trans.GetValueOrDefault(),
+ pngMetaData.Rgb24Trans.GetValueOrDefault());
break;
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index 411d5d69b..c76dc308b 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -292,7 +292,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (pngMetaData.HasTrans)
{
- //Write transparency header
+ this.WriteTransparencyMarkers(stream, pngMetaData);
}
this.WritePhysicalChunk(stream, metaData);
@@ -305,6 +305,50 @@ namespace SixLabors.ImageSharp.Formats.Png
quantized?.Dispose();
}
+ ///
+ /// Writes the transparency markers to the stream
+ ///
+ /// The containing image data.
+ /// The image meta data.
+ private void WriteTransparencyMarkers(Stream stream, PngMetaData pngMetaData)
+ {
+ if (pngMetaData.ColorType == PngColorType.Rgb)
+ {
+ if (pngMetaData.Rgb48Trans != null)
+ {
+ var r = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R);
+ var g = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.R);
+ var B = BitConverter.GetBytes(pngMetaData.Rgb48Trans.Value.B);
+
+ var alphaArray = r.Concat(g).Concat(B).ToArray();
+
+ this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length);
+ }
+ else if (pngMetaData.Rgb24Trans != null)
+ {
+ var alphaArray = new byte[6];
+ alphaArray[0] = pngMetaData.Rgb24Trans.Value.R;
+ alphaArray[2] = pngMetaData.Rgb24Trans.Value.G;
+ alphaArray[4] = pngMetaData.Rgb24Trans.Value.B;
+ this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length);
+ }
+ }
+ else if (pngMetaData.ColorType == PngColorType.Grayscale)
+ {
+ if (pngMetaData.Luminance16Trans != null)
+ {
+ var alphaArray = BitConverter.GetBytes(pngMetaData.Luminance16Trans.Value);
+
+ this.WriteChunk(stream, PngChunkType.PaletteAlpha, alphaArray, 0, alphaArray.Length);
+ }
+ else if (pngMetaData.LuminanceTrans != null)
+ {
+ var alphaArray = new byte[2];
+ alphaArray[0] = pngMetaData.LuminanceTrans.Value;
+ }
+ }
+ }
+
///
public void Dispose()
{
@@ -848,7 +892,10 @@ namespace SixLabors.ImageSharp.Formats.Png
/// Writes the chunk end to the stream.
///
/// The containing image data.
- private void WriteEndChunk(Stream stream) => this.WriteChunk(stream, PngChunkType.End, null);
+ private void WriteEndChunk(Stream stream)
+ {
+ this.WriteChunk(stream, PngChunkType.End, null);
+ }
///
/// Writes a chunk to the stream.
@@ -856,7 +903,10 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The to write to.
/// The type of chunk to write.
/// The containing data.
- private void WriteChunk(Stream stream, PngChunkType type, byte[] data) => this.WriteChunk(stream, type, data, 0, data?.Length ?? 0);
+ private void WriteChunk(Stream stream, PngChunkType type, byte[] data)
+ {
+ this.WriteChunk(stream, type, data, 0, data?.Length ?? 0);
+ }
///
/// Writes a chunk of a specified length to the stream at the given offset.
diff --git a/src/ImageSharp/Formats/Png/PngMetaData.cs b/src/ImageSharp/Formats/Png/PngMetaData.cs
index 0014defbb..765222795 100644
--- a/src/ImageSharp/Formats/Png/PngMetaData.cs
+++ b/src/ImageSharp/Formats/Png/PngMetaData.cs
@@ -47,22 +47,22 @@ namespace SixLabors.ImageSharp.Formats.Png
///
/// Gets or sets the Rgb 24 transparent color. This represents any color in an 8 bit Rgb24 encoded png that should be transparent
///
- public Rgb24 Rgb24Trans { get; set; }
+ public Rgb24? Rgb24Trans { get; set; }
///
/// Gets or sets the Rgb 48 transparent color. This represents any color in a 16 bit Rgb24 encoded png that should be transparent
///
- public Rgb48 Rgb48Trans { get; set; }
+ public Rgb48? Rgb48Trans { get; set; }
///
/// Gets or sets the 8 bit grayscale transparent color. This represents any color in an 8 bit grayscale encoded png that should be transparent
///
- public byte LuminanceTrans { get; set; }
+ public byte? LuminanceTrans { get; set; }
///
/// Gets or sets the 16 bit grayscale transparent color. This represents any color in a 16 bit grayscale encoded png that should be transparent
///
- public ushort Luminance16Trans { get; set; }
+ public ushort? Luminance16Trans { get; set; }
///
/// Gets or sets a value indicating whether the image has transparency chunk and markers were decoded