使用 .png 文件在 R 中创建动画 (.gif)

Posted

技术标签:

【中文标题】使用 .png 文件在 R 中创建动画 (.gif)【英文标题】:Creating animation (.gif) in R using .png files 【发布时间】:2018-08-25 11:19:45 【问题描述】:

样本数据

 location <- c("A","B","C")
 years <- c(2001,2002,2003)

 for(l in seq_along(location))
    for(y in seq_along(years))
       loc <- location[l]
       yr <- years[y]
       png(paste0(loc,".",yr,".png"))
       plot(rnorm(10))
       dev.off()
   
   

对于每个位置 X 年组合,我生成了 png 文件。我的目标是将每个位置,所有年份组合在一个 gif.file 中以显示为动画。

我正在这样做

  library(magick)

  # convert each png file as magick object 
  for(l in seq_along(location))
    for(y in seq_along(years))
       loc <- location[l]
       yr <- years[y]

       png.dat <- image_read(paste0(loc,".",yr,".png"))

       assign(paste0(loc,".",yr),png.dat)
   

这为我提供了位置 A、B 和 C 的以下文件:

A.2001、A.2002、A.2003 B.2001、B.2002、B.2003 C.2001、C.2002、C.2003

  # stack the objects for one location, and create animation
  A.c <- c(A.2001,A.2002,A.2003)
  A.img <- image_scale(A.c)
  A.ani <- image_animate(A.img, fps = 1, dispose = "previous")
  image_write(A.ani, paste0("A_animation.gif"))

  # repeat for B and C
   B.c <- c(B.2001,B.2002,B.2003)
   B.img <- image_scale(B.c)
   B.ani <- image_animate(B.img, fps = 1, dispose = "previous")
   image_write(B.ani, paste0("B_animation.gif"))

 # stack the objects for one location, and create animation
  C.c <- c(C.2001,C.2002,C.2003)
  C.img <- image_scale(C.c)
  C.ani <- image_animate(C.img, fps = 1, dispose = "previous")
  image_write(C.ani, paste0("C_animation.gif"))

我的问题是,实际上我有 100 多个地点和 30 年。所以上面创建动画的步骤变成了手动的。有没有人有更快的方法来完成上述任务。

【问题讨论】:

我不明白。哪些部分是“手动”的?您的代码会生成这些图像,因此您知道要将哪些文件输入到 imagemagick 中,对吧? A.c &lt;- c(A.2001,A.2002,A.2003) A.img &lt;- image_scale(A.c) A.ani &lt;- image_animate(A.img, fps = 1, dispose = "previous") image_write(A.ani, paste0("A_animation.gif")) 这部分是“手动”的。如果我有 1000 个位置,我必须编辑这部分 1000 次,将 A 替换为位置的相关名称 【参考方案1】:

您可以使用来自 magick 的image_join 将“magick-image”类的对象列表强制转换为多帧图像。

下面是我可以用你的例子来做的:

library(purrr)
library(magick)

location <- c("A","B","C")
years <- c(2001,2002,2003)

df <- data.frame(loc = character(0), yr = integer(0), file = character(0))

for(l in seq_along(location))
  for(y in seq_along(years))
    loc <- location[l]
    yr <- years[y]
    png(paste0(loc,".",yr,".png"))
    plot(rnorm(10))
    dev.off()
  


df <- expand.grid(loc = location,
                  yr = years)
df$file = paste0(df$loc,".",df$yr,".png")

df

#  loc   yr       file
# 1   A 2001 A.2001.png
# 2   B 2001 B.2001.png
# 3   C 2001 C.2001.png
# 4   A 2002 A.2002.png
# 5   B 2002 B.2002.png
# 6   C 2002 C.2002.png
# 7   A 2003 A.2003.png
# 8   B 2003 B.2003.png
# 9   C 2003 C.2003.png

locations <- unique(df$loc)

for(i in 1:length(locations)) 
  images <- map(df$file[df$loc == locations[i]], image_read)
  images <- image_join(images)
  animation <- image_animate(images, fps = 1)
  image_write(animation, paste0(locations[i], ".gif"))

【讨论】:

以上是关于使用 .png 文件在 R 中创建动画 (.gif)的主要内容,如果未能解决你的问题,请参考以下文章

将多个png转换为gif作为R中的动画

在 JavaScript 中创建 GIF 和 PNG

如何在 .net 中创建动画 gif

Android 将 gif 转换为动画 webp

如何在 Java 中创建动画 gif?

在 Cocoa 中创建动画 GIF - 定义帧类型