77using System . Runtime . InteropServices ;
88using SixLabors . ImageSharp . Common . Helpers ;
99using SixLabors . ImageSharp . Compression . Zlib ;
10+ using SixLabors . ImageSharp . Formats . Gif ;
1011using SixLabors . ImageSharp . Formats . Png . Chunks ;
1112using SixLabors . ImageSharp . Formats . Png . Filters ;
13+ using SixLabors . ImageSharp . Formats . Webp ;
1214using SixLabors . ImageSharp . Memory ;
1315using SixLabors . ImageSharp . Metadata ;
1416using SixLabors . ImageSharp . PixelFormats ;
@@ -137,7 +139,7 @@ public PngEncoderCore(Configuration configuration, PngEncoder encoder)
137139 /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
138140 /// <param name="cancellationToken">The token to request cancellation.</param>
139141 public void Encode < TPixel > ( Image < TPixel > image , Stream stream , CancellationToken cancellationToken )
140- where TPixel : unmanaged, IPixel < TPixel >
142+ where TPixel : unmanaged, IPixel < TPixel >
141143 {
142144 Guard . NotNull ( image , nameof ( image ) ) ;
143145 Guard . NotNull ( stream , nameof ( stream ) ) ;
@@ -146,7 +148,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
146148 this . height = image . Height ;
147149
148150 ImageMetadata metadata = image . Metadata ;
149- PngMetadata pngMetadata = metadata . GetFormatMetadata ( PngFormat . Instance ) ;
151+ PngMetadata pngMetadata = GetPngMetadata ( image ) ;
150152 this . SanitizeAndSetEncoderOptions < TPixel > ( this . encoder , pngMetadata , out this . use16Bit , out this . bytesPerPixel ) ;
151153
152154 stream . Write ( PngConstants . HeaderBytes ) ;
@@ -234,6 +236,54 @@ public void Dispose()
234236 this . currentScanline ? . Dispose ( ) ;
235237 }
236238
239+ private static PngMetadata GetPngMetadata < TPixel > ( Image < TPixel > image )
240+ where TPixel : unmanaged, IPixel < TPixel >
241+ {
242+ if ( image . Metadata . TryGetPngMetadata ( out PngMetadata ? png ) )
243+ {
244+ return png ;
245+ }
246+
247+ if ( image . Metadata . TryGetGifMetadata ( out GifMetadata ? gif ) )
248+ {
249+ AnimatedImageMetadata ani = gif . ToAnimatedImageMetadata ( ) ;
250+ return PngMetadata . FromAnimatedMetadata ( ani ) ;
251+ }
252+
253+ if ( image . Metadata . TryGetWebpMetadata ( out WebpMetadata ? webp ) )
254+ {
255+ AnimatedImageMetadata ani = webp . ToAnimatedImageMetadata ( ) ;
256+ return PngMetadata . FromAnimatedMetadata ( ani ) ;
257+ }
258+
259+ // Return explicit new instance so we do not mutate the original metadata.
260+ return new ( ) ;
261+ }
262+
263+ private static PngFrameMetadata GetPngFrameMetadata < TPixel > ( ImageFrame < TPixel > frame )
264+ where TPixel : unmanaged, IPixel < TPixel >
265+ {
266+ if ( frame . Metadata . TryGetPngMetadata ( out PngFrameMetadata ? png ) )
267+ {
268+ return png ;
269+ }
270+
271+ if ( frame . Metadata . TryGetGifMetadata ( out GifFrameMetadata ? gif ) )
272+ {
273+ AnimatedImageFrameMetadata ani = gif . ToAnimatedImageFrameMetadata ( ) ;
274+ return PngFrameMetadata . FromAnimatedMetadata ( ani ) ;
275+ }
276+
277+ if ( frame . Metadata . TryGetWebpFrameMetadata ( out WebpFrameMetadata ? webp ) )
278+ {
279+ AnimatedImageFrameMetadata ani = webp . ToAnimatedImageFrameMetadata ( ) ;
280+ return PngFrameMetadata . FromAnimatedMetadata ( ani ) ;
281+ }
282+
283+ // Return explicit new instance so we do not mutate the original metadata.
284+ return new ( ) ;
285+ }
286+
237287 /// <summary>
238288 /// Convert transparent pixels, to transparent black pixels, which can yield to better compression in some cases.
239289 /// </summary>
@@ -985,9 +1035,10 @@ private void WriteTransparencyChunk(Stream stream, PngMetadata pngMetadata)
9851035 /// <param name="stream">The <see cref="Stream"/> containing image data.</param>
9861036 /// <param name="imageFrame">The image frame.</param>
9871037 /// <param name="sequenceNumber">The frame sequence number.</param>
988- private FrameControl WriteFrameControlChunk ( Stream stream , ImageFrame imageFrame , uint sequenceNumber )
1038+ private FrameControl WriteFrameControlChunk < TPixel > ( Stream stream , ImageFrame < TPixel > imageFrame , uint sequenceNumber )
1039+ where TPixel : unmanaged, IPixel < TPixel >
9891040 {
990- PngFrameMetadata frameMetadata = imageFrame . Metadata . GetPngFrameMetadata ( ) ;
1041+ PngFrameMetadata frameMetadata = GetPngFrameMetadata ( imageFrame ) ;
9911042
9921043 // TODO: If we can clip the indexed frame for transparent bounds we can set properties here.
9931044 FrameControl fcTL = new (
0 commit comments