由于WebP项目的启动,于是需要了解如何将png或jpg格式的图片转化为WebP格式。但是网上的第三方工具并不能满足我们(无损压缩)的需求,因此,便自己开始学习起linux命令,来执行转换。
Google 给我们提供了转化为 WebP 的命令 lib。但是每次我们想要转化图片的时候,都需要用 cwebp 命令来对一张一张的图片进行转化,效率太低了。有没有什么办法可以一次性批量转化呢?
首先,我们来了解一下 Google 提供了什么命令来转化 webp 。
libwebp-0.4.1-mac-10.8.tar.gz

在 bin 目录下,我们要使用到得就是 cwebp 命令。
1 2
| ./cwebp -lossless a.png -o b.webp #使用cwebp命令 将 a.png 转化为 b.webp, -lossless 是无损压缩选项
|
- 注意:要想执行 cwebp 命令,必须先进入到 bin 目录!!!!除非你把这个命令配置到环境变量中。。。至于怎么配,我的另外一篇博客讲到了。
ok,知道怎么使用这个 cwebp 了,我们来想想怎么批量转化。
思路:我们希望“扔”进来一个图片文件夹,然后遍历该文件夹中所有的图片文件,并且执行转化。(ok,思路就是这么简单。)
既然我们想要遍历文件夹,那我们得知道类似 for 循环的语句在 shell 中如何书写。
1 2 3 4 5 6 7
| for var in file/dir do ... done #var 表示遍历文件夹中的单个文件 #do 表示你要做的操作 #done 表示循环结束
|
ok,到这里,我们的思路以及语法都大致了解了,下面贴上第一版的 shell 脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| for a in /路径/*.png do #打印变量 a 的值,比如:/User/picture/photo.png echo $a #删除变量 a 左侧最后一个出现/的所有字符,并赋值给 b b=${a##*/} #删除变量 b 右侧第一个出现.的所有字符,并复制给 c c=${b%.*} #打印变量 b 的值,如:photo.png echo $b #打印变量 c 的值,如:photo echo $c echo "----------------" #判断语句,如果是 c 的值是".9"结尾的话,将 .9图复制到指定的输出目录下。 if [[ $c == *\.9 ]]; then cp $a /输出的路径/$b else #若不是.9的图片,则执行无损转化。 ./cwebp -lossless $a -o /输出的路径/$c.webp fi done
|
到这里,以为大功告成了嘛?No,难道我们每次打开Terminal,然后一行一行的敲这个脚本么?我们得想个办法,写成个可执行文件,这样就方便多了嘛。另外,每次我们的输入的图片路径或者文件夹路径,灵活度不高,要是能从终端输入的该多好?
ok,说干就干,于是我们创建了一个文本,取名就叫 shell 好了。
我们想让它可执行,于是用到:
将 “shell” 赋予了可执行权限。
然后,我们想让用户自己输入图片的路径和转化后输出的路径,怎么做呢?
1 2 3 4 5 6
| #使用 read 语法,-p 选项表示用来提示的文字 input是个变量,表示输入的参数 #读取用户输入的输入路径(要转换的图片文件夹或图片文件) read -p "Please input include '.png' file or directory :" input
#读取用户输入的输出路径(转换成功后的图片文件夹或图片文件) read -p "Please input include '.webp' file or directory :" output
|
如上,这时我们的转化工具的易用性也提高了不少。
但是,第一版的 shell 脚本还存在了许多问题,例如:传进来的如果不是文件夹,而是图片呢?如果文件夹下的图片格式不只是png,还有jpg,或者别的格式呢?
另外,作为程序员,我们希望 coding 出来的代码符合“单一职责”原则。是否可以将转化的过程封装为一个函数或者方法呢?
于是,有了下面的这个“类终极版”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #读取用户输入的输入路径(要转换的图片文件夹或图片文件) read -p "Please input include '.png' file or directory :" input
#读取用户输入的输出路径(转换成功后的图片文件夹或图片文件) read -p "Please input include '.webp' file or directory :" output
#mPath=$input 调试用
#打印路径 echo $input echo $output
#test ! -f $mPath && echo "This is not file" 调试用
#转化单个图片的函数 function convertPic(){ name=${input##*/} echo $name; c=${name%.*} echo $c ./cwebp -lossless $input -o $output/$c.webp exit 0; }
#转化文件夹下多个图片(只转化png格式的图片,其他格式(jpg,gif,.9图片)只是拷贝到指定输出的目录下) function convertPicDirectory(){ for a in $input/* do echo "a="$a b=${a##*/} c=${b%.*} echo "b="$b echo "c="$c echo "----------------" if [[ $c == *\.9 ]]; then cp $a $output/$b elif [[ $b == *\.jpg ]]; then cp $a $output/$b elif [[ $b == *\.gif ]]; then cp $a $output/$b else ./cwebp -lossless $a -o $output/$c.webp fi done exit 0; } #判断输入的路径是否存在 if [ -e "$input" ]; then echo "\n$input: is exist" else echo "\nNo such file or directory" fi
#判断输入的路径是否存在且为文件夹 if [ -d "$input" ]; then #如果是正确的文件夹,则开始遍历文件夹做转换操作 echo "This is correct directory" #调用函数开始转换 convertPicDirectory;
#不是文件夹 else #调用函数开始转换单个图片文件 convertPic; echo "\nThis is not directory" fi
|
ok,到这里,目前的webp转化小脚本到此为止啦~虽然还有很多不足,例如:
1.不支持文件夹下的递归遍历、转化操作。
2.只是单一的支持png的无损压缩。
3.……
下面附上个人这个小工具的GitHub地址:https://github.com/lianyuchen/WebpConvertTool
希望大家多多star,给我点鼓励~
作者 :
Lian Yuchen(ShadowHappiness)
著作权归作者所有,转载请联系作者获得授权。