@@ -161,6 +161,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
161
161
162
162
ImageFrame < TPixel > ? clonedFrame = null ;
163
163
ImageFrame < TPixel > currentFrame = image . Frames . RootFrame ;
164
+ int currentFrameIndex = 0 ;
164
165
165
166
bool clearTransparency = this . encoder . TransparentColorMode is PngTransparentColorMode . Clear ;
166
167
if ( clearTransparency )
@@ -190,28 +191,49 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
190
191
if ( image . Frames . Count > 1 )
191
192
{
192
193
this . WriteAnimationControlChunk ( stream , ( uint ) image . Frames . Count , pngMetadata . RepeatCount ) ;
194
+ }
195
+
196
+ // If the first frame isn't animated, write it as usual and skip it when writing animated frames
197
+ if ( ! pngMetadata . DefaultImageAnimated || image . Frames . Count == 1 )
198
+ {
199
+ FrameControl frameControl = new ( ( uint ) this . width , ( uint ) this . height ) ;
200
+ this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
201
+ currentFrameIndex ++ ;
202
+ }
193
203
194
- // Write the first frame.
204
+ if ( image . Frames . Count > 1 )
205
+ {
206
+ // Write the first animated frame.
207
+ currentFrame = image . Frames [ currentFrameIndex ] ;
195
208
PngFrameMetadata frameMetadata = GetPngFrameMetadata ( currentFrame ) ;
196
209
PngDisposalMethod previousDisposal = frameMetadata . DisposalMethod ;
197
210
FrameControl frameControl = this . WriteFrameControlChunk ( stream , frameMetadata , currentFrame . Bounds ( ) , 0 ) ;
198
- this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
211
+ uint sequenceNumber = 1 ;
212
+ if ( pngMetadata . DefaultImageAnimated )
213
+ {
214
+ this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
215
+ }
216
+ else
217
+ {
218
+ sequenceNumber += this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , true ) ;
219
+ }
220
+
221
+ currentFrameIndex ++ ;
199
222
200
223
// Capture the global palette for reuse on subsequent frames.
201
224
ReadOnlyMemory < TPixel > ? previousPalette = quantized ? . Palette . ToArray ( ) ;
202
225
203
226
// Write following frames.
204
- uint increment = 0 ;
205
227
ImageFrame < TPixel > previousFrame = image . Frames . RootFrame ;
206
228
207
229
// This frame is reused to store de-duplicated pixel buffers.
208
230
using ImageFrame < TPixel > encodingFrame = new ( image . Configuration , previousFrame . Size ( ) ) ;
209
231
210
- for ( int i = 1 ; i < image . Frames . Count ; i ++ )
232
+ for ( ; currentFrameIndex < image . Frames . Count ; currentFrameIndex ++ )
211
233
{
212
234
ImageFrame < TPixel > ? prev = previousDisposal == PngDisposalMethod . RestoreToBackground ? null : previousFrame ;
213
- currentFrame = image . Frames [ i ] ;
214
- ImageFrame < TPixel > ? nextFrame = i < image . Frames . Count - 1 ? image . Frames [ i + 1 ] : null ;
235
+ currentFrame = image . Frames [ currentFrameIndex ] ;
236
+ ImageFrame < TPixel > ? nextFrame = currentFrameIndex < image . Frames . Count - 1 ? image . Frames [ currentFrameIndex + 1 ] : null ;
215
237
216
238
frameMetadata = GetPngFrameMetadata ( currentFrame ) ;
217
239
bool blend = frameMetadata . BlendMethod == PngBlendMethod . Over ;
@@ -232,22 +254,17 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
232
254
}
233
255
234
256
// Each frame control sequence number must be incremented by the number of frame data chunks that follow.
235
- frameControl = this . WriteFrameControlChunk ( stream , frameMetadata , bounds , ( uint ) i + increment ) ;
257
+ frameControl = this . WriteFrameControlChunk ( stream , frameMetadata , bounds , sequenceNumber ) ;
236
258
237
259
// Dispose of previous quantized frame and reassign.
238
260
quantized ? . Dispose ( ) ;
239
261
quantized = this . CreateQuantizedImageAndUpdateBitDepth ( pngMetadata , encodingFrame , bounds , previousPalette ) ;
240
- increment += this . WriteDataChunks ( frameControl , encodingFrame . PixelBuffer . GetRegion ( bounds ) , quantized , stream , true ) ;
262
+ sequenceNumber += this . WriteDataChunks ( frameControl , encodingFrame . PixelBuffer . GetRegion ( bounds ) , quantized , stream , true ) + 1 ;
241
263
242
264
previousFrame = currentFrame ;
243
265
previousDisposal = frameMetadata . DisposalMethod ;
244
266
}
245
267
}
246
- else
247
- {
248
- FrameControl frameControl = new ( ( uint ) this . width , ( uint ) this . height ) ;
249
- this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
250
- }
251
268
252
269
this . WriteEndChunk ( stream ) ;
253
270
0 commit comments