I am struggling to understand a couple of things about what the
magick package is doing, and whether there are better ways to use it. If more appropriate, I’m happy to repost this on SO, please just let me know.
I’m having trouble using
magick to stitch together two gifs from
gganimate, as described here: https://github.com/thomasp85/gganimate/issues/140.
My two specific questions (a lot more detail below):
image_animate()seem to scale badly with the number of frames (i.e. execution time seems to increase much more than linearly with number of frames)?
What is the difference between calling a magick object directly to get the animation, and calling
image_animate()(in my hands, the
It works OK. It’s just that building the final animation with
magick is reaaally slow, and I’m trying to understand why, to see if there’s anything I can do about it. (Note: this is for a package we’re developing, so I’m seeking to understand whether this can be sped up to the point that it will be useable for others).
Here’s what I’m doing:
- Creating two gifs with the same number of frames using
- Decomposing both gifs into individual images using
image_read()(this is very fast)
- Combining the frames one-by-one using
newframe <- image_append(c(frame_a, frame_b))then
final_gif <- c(final_gif, new_frame)(this is also fast)
Here’s what the
final_gif looks like, for information:
# A tibble: 150 x 7 format width height colorspace matte filesize density <chr> <int> <int> <chr> <lgl> <int> <chr> 1 GIF 600 550 sRGB TRUE 0 72x72 2 GIF 600 550 sRGB TRUE 0 72x72 3 GIF 600 550 sRGB TRUE 0 72x72 4 GIF 600 550 sRGB TRUE 0 72x72 5 GIF 600 550 sRGB TRUE 0 72x72 6 GIF 600 550 sRGB TRUE 0 72x72 7 GIF 600 550 sRGB TRUE 0 72x72 8 GIF 600 550 sRGB TRUE 0 72x72 9 GIF 600 550 sRGB TRUE 0 72x72 10 GIF 600 550 sRGB TRUE 0 72x72 # … with 140 more rows
Now the questions.
Question 1: Why does
image_animate() step scale badly with the number of frames? And is there any way to get around this?
(Note: I don’t see the same issues in
gganimate, where the animation steps scale roughly linearly with the number of frames, as I’d naively expect).
Here are some timings from
system.time() with different numbers of frames to illustrate:
30 frames: 2.1s
60 frames: 4.2s
120 frames: 11.2s (so far so linear)
240 frames: 251s (not so linear anymore)
FWIW, it doesn’t seem to be a memory issue, because I tracked memory usage and saw no issues.
Question 2: What is the difference between calling the magick object directly (i.e.
final_gif), and calling
I note two big differences (which I assume are related). The above scaling issue seems a lot worse when calling the object directly; and calling
image_animate() gives really horrible grainy gifs (in RStudio at least), while calling the object directly gives beautifully rendered gifs with all of their pixels.
If anyone can shed any light on either of these issues, I’d be very interested. Happy to build replicable examples if it helps.