diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index bb800c8a4..292de007c 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -760,9 +760,9 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The image meta data.
private void WriteTransparencyChunk(Stream stream, PngMetaData pngMetaData)
{
+ Span alpha = this.chunkDataBuffer.AsSpan();
if (pngMetaData.ColorType.Equals(PngColorType.Rgb))
{
- Span alpha = this.buffer.AsSpan();
if (pngMetaData.TransparentRgb48.HasValue && this.use16Bit)
{
Rgb48 rgb = pngMetaData.TransparentRgb48.Value;
@@ -770,7 +770,7 @@ namespace SixLabors.ImageSharp.Formats.Png
BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(2, 2), rgb.G);
BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(4, 2), rgb.B);
- this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6);
+ this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 6);
}
else if (pngMetaData.TransparentRgb24.HasValue)
{
@@ -779,22 +779,21 @@ namespace SixLabors.ImageSharp.Formats.Png
alpha[1] = rgb.R;
alpha[3] = rgb.G;
alpha[5] = rgb.B;
- this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6);
+ this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 6);
}
}
else if (pngMetaData.ColorType.Equals(PngColorType.Grayscale))
{
- Span alpha = this.buffer.AsSpan();
if (pngMetaData.TransparentGray16.HasValue && this.use16Bit)
{
BinaryPrimitives.WriteUInt16LittleEndian(alpha, pngMetaData.TransparentGray16.Value.PackedValue);
- this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2);
+ this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 2);
}
else if (pngMetaData.TransparentGray8.HasValue)
{
alpha.Clear();
alpha[1] = pngMetaData.TransparentGray8.Value.PackedValue;
- this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2);
+ this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 2);
}
}
}
diff --git a/src/ImageSharp/Formats/Png/PngMetaData.cs b/src/ImageSharp/Formats/Png/PngMetaData.cs
index 6a293f770..d5ab3d255 100644
--- a/src/ImageSharp/Formats/Png/PngMetaData.cs
+++ b/src/ImageSharp/Formats/Png/PngMetaData.cs
@@ -26,6 +26,11 @@ namespace SixLabors.ImageSharp.Formats.Png
this.BitDepth = other.BitDepth;
this.ColorType = other.ColorType;
this.Gamma = other.Gamma;
+ this.HasTrans = other.HasTrans;
+ this.TransparentGray8 = other.TransparentGray8;
+ this.TransparentGray16 = other.TransparentGray16;
+ this.TransparentRgb24 = other.TransparentRgb24;
+ this.TransparentRgb48 = other.TransparentRgb48;
}
///
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
index 5d328db36..9079b15fb 100644
--- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
@@ -25,6 +25,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
{ TestImages.Png.Bpp1, PngBitDepth.Bit1 }
};
+ public static readonly TheoryData PngTrnsFiles =
+ new TheoryData
+ {
+ { TestImages.Png.Gray1BitTrans, PngBitDepth.Bit1, PngColorType.Grayscale },
+ { TestImages.Png.Gray2BitTrans, PngBitDepth.Bit2, PngColorType.Grayscale },
+ { TestImages.Png.Gray4BitTrans, PngBitDepth.Bit4, PngColorType.Grayscale },
+ { TestImages.Png.Gray8BitTrans, PngBitDepth.Bit8, PngColorType.Grayscale },
+ { TestImages.Png.GrayTrns16BitInterlaced, PngBitDepth.Bit16, PngColorType.Grayscale },
+ { TestImages.Png.Rgb24BppTrans, PngBitDepth.Bit8, PngColorType.Rgb },
+ { TestImages.Png.Rgb48BppTrans, PngBitDepth.Bit16, PngColorType.Rgb }
+ };
+
///
/// All types except Palette
///
@@ -249,6 +261,61 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
}
+ [Theory]
+ [MemberData(nameof(PngTrnsFiles))]
+ public void Encode_PreserveTrns(string imagePath, PngBitDepth pngBitDepth, PngColorType pngColorType)
+ {
+ var options = new PngEncoder();
+
+ var testFile = TestFile.Create(imagePath);
+ using (Image input = testFile.CreateImage())
+ {
+ PngMetaData inMeta = input.MetaData.GetFormatMetaData(PngFormat.Instance);
+ Assert.True(inMeta.HasTrans);
+
+ using (var memStream = new MemoryStream())
+ {
+ input.Save(memStream, options);
+ memStream.Position = 0;
+ using (var output = Image.Load(memStream))
+ {
+ PngMetaData outMeta = output.MetaData.GetFormatMetaData(PngFormat.Instance);
+ Assert.True(outMeta.HasTrans);
+
+ switch (pngColorType)
+ {
+ case PngColorType.Grayscale:
+ if (pngBitDepth.Equals(PngBitDepth.Bit16))
+ {
+ Assert.True(outMeta.TransparentGray16.HasValue);
+ Assert.Equal(inMeta.TransparentGray16, outMeta.TransparentGray16);
+ }
+ else
+ {
+ Assert.True(outMeta.TransparentGray8.HasValue);
+ Assert.Equal(inMeta.TransparentGray8, outMeta.TransparentGray8);
+ }
+
+ break;
+ case PngColorType.Rgb:
+ if (pngBitDepth.Equals(PngBitDepth.Bit16))
+ {
+ Assert.True(outMeta.TransparentRgb48.HasValue);
+ Assert.Equal(inMeta.TransparentRgb48, outMeta.TransparentRgb48);
+ }
+ else
+ {
+ Assert.True(outMeta.TransparentRgb24.HasValue);
+ Assert.Equal(inMeta.TransparentRgb24, outMeta.TransparentRgb24);
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
private static void TestPngEncoderCore(
TestImageProvider provider,
PngColorType pngColorType,
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 8da458e52..1144a3f7c 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -46,6 +46,9 @@ namespace SixLabors.ImageSharp.Tests
public const string PDSrc = "Png/pd-source.png";
public const string PDDest = "Png/pd-dest.png";
public const string Gray1BitTrans = "Png/gray-1-trns.png";
+ public const string Gray2BitTrans = "Png/gray-2-tRNS.png";
+ public const string Gray4BitTrans = "Png/gray-4-tRNS.png";
+ public const string Gray8BitTrans = "Png/gray-8-tRNS.png";
// Filtered test images from http://www.schaik.com/pngsuite/pngsuite_fil_png.html
public const string Filter0 = "Png/filter0.png";
diff --git a/tests/Images/Input/Png/gray-2-tRNS.png b/tests/Images/Input/Png/gray-2-tRNS.png
new file mode 100644
index 000000000..d5657ac34
--- /dev/null
+++ b/tests/Images/Input/Png/gray-2-tRNS.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c36d10c8498bbe148bc44d41e0243137e47b07402dfb8e58978d1a9b5029cabc
+size 265
diff --git a/tests/Images/Input/Png/gray-4-tRNS.png b/tests/Images/Input/Png/gray-4-tRNS.png
new file mode 100644
index 000000000..01c1b6992
--- /dev/null
+++ b/tests/Images/Input/Png/gray-4-tRNS.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:217248c079a0ed7896803a2bf5d9719b6060ef898314a5f6ab898c6c4349f341
+size 267
diff --git a/tests/Images/Input/Png/gray-8-tRNS.png b/tests/Images/Input/Png/gray-8-tRNS.png
new file mode 100644
index 000000000..9b0b78ce5
--- /dev/null
+++ b/tests/Images/Input/Png/gray-8-tRNS.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6e14dce9350fc40f7ee542d1dc788fbf6c1c0178515ea8b76ffa0b18bcf54e8a
+size 267