4

I'm trying to create a short animation with several png files in R. I tried package magick but it only works when I save them to .gif. When I tried to save as .mp4, it will generate an .mp4 file but once you open it, only the first image will be shown.

My code is

  library(magick)
  productPath <- ('/Users/abc/Desktop/products/')
  list <- list.files(productPath, '*.png')
  imagesPath <- paste0(productPath, list)
  images <- image_read(imagesPath)
  animation <- image_animate(images, fps = 20, loop = 1)
  image_write(animation, paste0(productPath, 'test.mp4'))

I found there is also a package called animation, but I don't really know how to import png files with that package. Any solutions? With either package should be fine. Thank you!

lobati
  • 9,284
  • 5
  • 40
  • 61
Arthur
  • 398
  • 6
  • 20

3 Answers3

8

The selected best answer requires you to install ffmpeg first. If you haven't and due to limited administrative right you can't install other programs on you PC you can try the av package.

This works without needing to install any other program.

av::av_encode_video(list.files(productPath, '*.png'), framerate = 30,
                    output = 'test.mp4')
moho wu
  • 471
  • 4
  • 13
4

You can do like this (assuming the images are in the current directory):

library(animation)
imgs <- list.files(pattern="*.png")
saveVideo({
  for(img in imgs){
    im <- magick::image_read(img)
    plot(as.raster(im))
  }  
})

By default this create animation.mp4.

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Hi Stéphane, thank you very much. it works for me. Just a quick question. The video it generated has big white margins, can we remove them? – Arthur Jul 13 '18 at 14:07
  • @Arthur These margins are the margins of the png files ? Or they are additional margins ? In the first case you would have to modify the png files, perhaps with `crop` or `trim` of ImageMagick. In the second case I don't know. Maybe by changing some options of `saveVideo` (the `width` option perhaps). If your images are available somewhere I can try. – Stéphane Laurent Jul 13 '18 at 14:52
  • I think they are additional margins since the png files themselves don't have margins. So what happened to your files? When you ran the code above, did it give additional margins for you in the video? – Arthur Jul 13 '18 at 15:02
  • @Arthur I can't say because the images I tried have white background. I will try with other images, wait. – Stéphane Laurent Jul 13 '18 at 15:03
  • @Arthur I've tried. The `width` option does not help. In fact `saveVideo` runs the `ffmpeg` program. The only solution I see is to run `ffmpeg` in the command line, without R. Then it should be possible to crop the images (this question has been raised on `superuser`). – Stéphane Laurent Jul 13 '18 at 15:14
  • Ah no, there is a `other.opts` argument in `saveVideo`. This is intended to pass additional options to `ffmpeg`. So it should be possible to do from R. – Stéphane Laurent Jul 13 '18 at 15:18
  • @Arthur This does look easy however. Look e.g https://video.stackexchange.com/questions/4563/how-can-i-crop-a-video-with-ffmpeg. In fact I'm even not sure this is to get rid of the margins. – Stéphane Laurent Jul 13 '18 at 15:20
  • @Arthur are the margins not introduced when using `plot()`? I got rid of mine by setting `par(mar = rep(0,4))` before the call to `plot()` – guyabel Nov 15 '18 at 00:13
3
library(purrr)
library(magick)
list.files(pattern = "*.png") %>% 
    map(image_read) %>% # reads each path file
    image_join() %>% # joins image
    image_animate(fps=5) %>% # animates
    image_write("animation.gif") # write to current dir