电鸭原创,如需转载,请联系作者。
ps:作者本人待业中,求一份远程全职工作岗位(全栈)
PHP一般是作为一种后端的开发语言。但是实际上语言是共通的,只要调用合适的库,PHP也同样可以做一些前端的事情,比如实现视频动画编程。
先说一下总体的思路和需要用的库。
1、php-gd。PHP可以使用php-gd进行一些基本的绘图。包括绘制形状,填充颜色,读取图片,粘贴图形,输出图片等。
2、ffmpeg。在windows上调用ffmpeg命令,可以实现将静态图片组合输出为视频。 看了这2点提示,您应该看出来,我们当然的,是可以通过php-gd,生成动画的每一帧的图片,储存在文件系统中,操作完成后,然后调用ffmpeg命令,将图片输出为视频。
第二步是比较简单的。我这里不多赘述,把命令格式写在下面:
ffmpeg -f image2 -i [目录]/%d.jpg [目标输出地址]
其中"[目录]/%d.jpg"是源图片的存储地址。图片在目录中应该按照帧顺序的数字存储。例如:1.jpg,2,jpg,3.jpg。
操作的关键是第一步,生成动画的帧。初看上去这个任务是很庞大的。但是实际上,这和在cavas中绘图没有什么本质的区别。当然,php的绘图功能,不如其它专业的前端语言那么强大。所以肯定没办法做到像canvas那样的复杂的动画。
这里说一下我的开发思路。
首先明确概念:
1、元素管理。这里把整个动画想象为一个视界。世界里每一个单元想象为一个元素。这里的元素概念相当于canvas动画里一些物理库的sprite。必须要创建sprite概念。否则整个动画复杂化以后没法管理。sprite里面有width,height,opacity,x,y等概念,也是和canvas的常见物理库一样的。还有元素的父子关系管理,以及父子关系的相对位置处理等,都是一样的。
2、帧数据管理。元素的每一个属性,例如width,height,x,y,opacity等,都有一个当前值和目标值的概念。目标值,就是这个元素,准备往哪个值变化。帧数据的话,就是元素管理的时间和空间双重映射的一个结果。时间映射,就是元素每一步的变化记录,都要放在帧数据里。空间映射,就是元素的父子关系平坦化后的结果放在帧数据里。
3、图片生成。把帧数据生成为图片。例如一个正方形元素,根据正方形的x,y,width,height,opacity以及颜色,调用gd库的相应函数,生成在画布上。所有的帧数据都生成后,将画布输出到帧顺序对应的物理文件里保存。
这里比如说,我们要做一个从小到大变化的正方形的动画。
通过以上三步操作,我们就可以实现php生成动画的帧图片集合。然后调用ffmpeg命令,就可以将图片集合,生成为mp4视频啦!
那么这种比较偏僻的创建动画方式,能有什么用呢?其实,这主要是因为作者本身也是一个业余的视频自媒体创作人。有时候视频中,会需要用一些类似于时间流水线式的动画讲解。这种动画,风格都是完全一样的。如果一个一个去做的话,比较费力。于是我想到按照一定的规则进行配置,然后自动生成。但是js canvas制作的动画,没办法保存为mp4视频。于是我想到了用PHP GD库和FFMPEG的方式进行创作。怎样,还不错吧~
补充一下,有些同学可能会想,用php这样一个非专业前端的语言,做这种工作,效率会不会很低呢。
其实,只要实现了一些基础的类用于管理sprite,开发效率和其它语言是一样的,简单的语法差别,并不是太影响开发效率的,真正影响开发效率的,是人的思维,您觉得呢
第二,这样生成动画的话,如果是用web操作的话,确实效率是比较慢的。但是如果是用命令行的方式执行php的话,生成效率是很高的。我直观上感觉,不比flash生成动画更慢!