Commit 741d4d240 for imagemagick.org
commit 741d4d2403455c3a1fee32fe5f14217901ce438a
Author: Madars <mad182@gmail.com>
Date: Wed Mar 25 11:54:52 2026 +0200
Fix APNG output duration/framerate (#8639)
When writing APNG via ffmpeg in the VIDEO coder, ImageMagick bypasses the frame
duplication hack (by setting length_of_delay_loop = 1). As a result, exactly one
intermediate file is passed to ffmpeg for each original frame. Because ffmpeg
assumes 25 fps for image sequence inputs and no framerate was explicitly passed,
the output APNG was always forced to exactly 25 fps (40ms per frame), ignoring
the actual image delay.
This commit appends a precise setpts and -r override to the ffmpeg options
for APNG outputs, stretching or squeezing the input PTS perfectly to match
the requested time_per_frame and ensuring the correct APNG metadata is written.
diff --git a/coders/video.c b/coders/video.c
index ec18493c7..72047bce1 100644
--- a/coders/video.c
+++ b/coders/video.c
@@ -711,6 +711,21 @@ static MagickBooleanType WriteVIDEOImage(const ImageInfo *image_info,
" -pix_fmt \"%s\""," -pix_fmt '%s'",option);
(void) ConcatenateMagickString(options,command,MagickPathExtent);
}
+ if (LocaleNCompare(image_info->magick,"APNG",MagickPathExtent) == 0)
+ {
+ double
+ time_per_frame;
+
+ time_per_frame=1.0*clone_images->delay/MagickMax(1.0*
+ clone_images->ticks_per_second,1.0);
+ if (time_per_frame > 0.0)
+ {
+ (void) FormatLocaleString(command,MagickPathExtent,
+ " -filter:v \"setpts=(25*%.20g)*PTS\" -r 1/%.20g",
+ time_per_frame,time_per_frame);
+ (void) ConcatenateMagickString(options,command,MagickPathExtent);
+ }
+ }
AcquireUniqueFilename(write_info->unique);
(void) FormatLocaleString(command,MagickPathExtent,
GetDelegateCommands(delegate_info),basename,intermediate_format,