用R制作gif动态图以及从gif中提取图片


欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

 对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

作者:辉小宝同学

微信公众号:R语言和Python学堂

知乎:https://www.zhihu.com/people/zoro-3-92/posts

简书:https://www.jianshu.com/u/981ba7d6b4a6

熟悉R的朋友,肯定知道 animation包,它可将一系列用R绘制的静态图转化为各种格式的动图或视频(比如:gif, mp4, avi等格式)。事实上,它是通过R去调用一些图片或视频处理程序(比如:ImageMagick, GraphicsMagick, FFmpeg等)来实现这些功能的,因此如果要使用这些功能,相应外部程序也必须要安装。关于 animation包的详情可参考https://cran.r-project.org/web/packages/animation/。

由于 animation包只能将R绘制的静态图转化为动图,它不能处理外部图片以及gif动态图。因此我将在这篇博客教大家如何用R从gif中提取图片以及如何将外部图片制作成gif动态图,我将以下面的gif动图为例:

用R制作gif动态图以及从gif中提取图片

1. 下载ImageMagick

ImageMagick是一款功能强大、稳定而且免费开源的图片处理工具集,可以用来读、写和处理超过200种不同格式的图片文件,详情可参考其官网https://www.imagemagick.org。

这里我们也将通过R来调用ImageMagick来实现我们的功能。我们用的是ImageMagick的Windows portable版(便携版,也即免安装版),我将安装压缩包已上传至百度网盘(包括32位和64位系统的,解压就可以用,无需安装),你也可从官网下载https://www.imagemagick.org/script/download.php。

用R制作gif动态图以及从gif中提取图片

2. 从gif动图中提取每帧图片

在ImageMagick中可通过命令行模式来实现这个功能,其一般命令为convert test.gif-coalesce result_%05d.png。下面通过R来调用这个命令,我将其封装成一个叫 gif2frames()的函数,其各参数的意义见函数内部的注释:


  1. gif2frames <- function(pathIn='',

  2.                       pathOut='',

  3.                       ImageMagick_path='',

  4.                       frameFormat='png',

  5.                       prefixFrame='/frame_%05d.'){

  6.  ##### arguments

  7.  # pathIn: gif文件所在路径

  8.  # pathOut: 图片保存路径

  9.  # ImageMagick_path: ImageMagick convert命令所在路径

  10.  # frameFormat: 图片保存的格式类型

  11.  # prefixFrame: 图片文件名的格式

  12.  ##### return

  13.  # None

  14.  if(!dir.exists(pathOut))  ##自动创建保存图片的文件夹

  15.    dir.create(pathOut)

  16.  command <- paste(ImageMagick_path, pathIn, '-coalesce', paste0(pathOut, prefixFrame, frameFormat))

  17.  #system('F:R_tutorials/gif/ImageMagick-7.0.8-64bit/convert test.gif -coalesce ./frames/frame_%05d.png')

  18.  system(command)  ##调用外部的ImageMagick程序

  19. }

从上面代码可知,最后我们通过R中的 system()函数来调用外部ImageMagick程序来实现所需功能。

来测试一下:


  1. pathIn <- 'test.gif'

  2. pathOut <- './frames/'

  3. ImageMagick_path <- './ImageMagick-7.0.8-64bit/convert'


  4. gif2frames(pathIn, pathOut, ImageMagick_path)

运行完上面代码后, test.gif动图中的每一帧都保存在 frames文件夹下,如下图:

用R制作gif动态图以及从gif中提取图片

用R提取gif中的每帧图片就算实现了,是不是很简单!!!

3. 制作gif

下面我将使用上一步提取到的图片(即 frames文件夹下的170帧图片)为例,来介绍如何制作gif,这可以看作为上一步的逆过程。我也将其封装成一个叫 frames2gif的函数:


  1. frames2gif <- function(pathIn='',

  2.                       pathOut='',

  3.                       ImageMagick_path='',

  4.                       resize_ratio=1,

  5.                       delay=40,

  6.                       frameFormat='png',

  7.                       everyFrame=1){

  8.  ##### arguments

  9.  # pathIn: 图片所在路径

  10.  # pathOut: 生成的gif所保存的路径

  11.  # ImageMagick_path: ImageMagick convert命令所在路径

  12.  # resize_ratio: 调节gif的尺寸,默认为1。如果为0.5,gif的长度和宽度将是图片尺寸的一半

  13.  # delay: 设置帧与帧之间的时间间隔,默认为40(表示0.4s)。如果为200,那么时间间隔即为2s

  14.  # frameFormat: 图片的格式

  15.  # everyFrame: 如果为3,只使用pathIn文件夹下的第1, 4, 7,10,13帧,.....图片来制作gif,默认使用所有图片

  16.  ##### return

  17.  # None


  18.  ## create temp dir to store frames used to create gif.

  19.  tempdir <- paste0(pathIn, '/temp')

  20.  dir.create(tempdir)

  21.  files <- list.files(pathIn, pattern=paste0('*.', frameFormat), recursive=FALSE, full.names=TRUE)

  22.  index <- seq(1, length(files), by=everyFrame)

  23.  file.copy(files[index], tempdir)

  24.  command <- paste(ImageMagick_path,

  25.                   '-resize', paste0(as.integer(100L*resize_ratio), '%'),

  26.                   '-delay', delay,

  27.                   paste0(tempdir,'/*.', frameFormat),

  28.                   pathOut)

  29.  #system('F:R_tutorials/gif/ImageMagick-7.0.8-64bit/convert -resize 90% -delay 40 *.png result.gif')

  30.  system(command)

  31.  ## delete temp dir

  32.  unlink(tempdir, recursive=TRUE, force=TRUE)

  33. }

来测试一下:

1. 设置 delay参数为 2(也即帧与帧之间的时间间隔为0.02s),使动画变得更快。


  1. pathIn <- './frames/'

  2. pathOut <- 'fast.gif'

  3. ImageMagick_path <- './ImageMagick-7.0.8-64bit/convert'


  4. frames2gif(pathIn, pathOut,

  5.           ImageMagick_path,

  6.           delay=2)

结果如下图:

用R制作gif动态图以及从gif中提取图片

2. 设置 resize_ratio参数为 0.5,使动画尺寸大小变为原来的一半。


  1. pathOut <- 'small.gif'


  2. frames2gif(pathIn, pathOut,

  3.           ImageMagick_path,

  4.           resize_ratio=0.5,

  5.           delay=4)

结果如下图:

用R制作gif动态图以及从gif中提取图片

3. 设置 everyFrame参数为 2,使动画的总帧数变为原来的1/2。


  1. pathOut <- 'small_frames.gif'


  2. frames2gif(pathIn, pathOut,

  3.           ImageMagick_path,

  4.           everyFrame=2,

  5.           delay=4)

结果如下图:

用R制作gif动态图以及从gif中提取图片

从上图可知,减少动画总帧数,其效果相当于缩短动画时间。

通过以上三个例子,我们知道如何使用 frames2gif()函数来制作gif动图了。

以上就是本文的全部内容,希望对大家的学习有所帮助。如果觉得文章不错,动手转发支持一下哦!

用R制作gif动态图以及从gif中提取图片

用R制作gif动态图以及从gif中提取图片

公众号后台回复关键字即可学习

回复 爬虫             爬虫三大案例实战  
回复 Python        1小时破冰入门

回复 数据挖掘      R语言入门及数据挖掘
回复 人工智能      三个月入门人工智能
回复 数据分析师   数据分析师成长之路 
回复 机器学习      机器学习的商业应用
回复 数据科学      数据科学实战
回复 常用算法      常用数据挖掘算法

用R制作gif动态图以及从gif中提取图片
用R制作gif动态图以及从gif中提取图片
爱我请给我好看!
用R制作gif动态图以及从gif中提取图片