最近遇到一个需求,批量处理图标,如果用 Photoshop 一个个去处理的话非常麻烦,于是我就想写一个 shell 脚本去处理,(在以前搞 RN 的时候用过一个 icon 处理脚本,我也许也可以去试下?)我发现它其实也是使用 ImageMagick 去处理图片的,我估计大部分在线处理图片的网页都是用这个强大的工具的吧…

客户端我们可以用 PhotoShop 等 GUI 工具处理静态图片或者动态 GIF 图片,不过在服务器端对于 WEB 应用程序要处理图片格式转换,缩放裁剪,翻转扭曲,PDF解析等操作, GUI 软件就很难下手了,所以此处需要召唤命令行工具来帮我们完成这些事。

ImageMagick: 是一款创建、编辑、合成,转换图像的命令行工具。支持格式超过 200 种,包括常见的 PNG, JPEG, GIF, HEIC, TIFF, DPX, EXR, WebP, Postscript, PDF, SVG 等。功能包括调整,翻转,镜像(mirror),旋转,扭曲,修剪和变换图像,调整图像颜色,应用各种特殊效果,或绘制文本,线条,多边形,椭圆和贝塞尔曲线等。

官网:https://www.imagemagick.org

Mac OS 使用 Brew 安装

brew install imagemagick

在 shell 脚本可以这么去判断是否安装 imagemagick (我写的 shell 脚本可能有点啰嗦,我看过大神写的基本一句话就可以搞定,继续努力,哇咔咔咔):


# 判断 imagemagick 是否安装
is_code_app_112233="convert"
if ! [ -x "$(command -v $is_code_app_112233)" ]; then
  # echo "Error: $appName is not installed." >&2
  if ! [ -x "$(command -v brew)" ]; then
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  fi
  brew install imagemagick
fi

我这里只是简单讲讲我是怎么去使用这个工具去处理我的图片的,如果需要深入去学习推荐去官网看官方文档或是去网上找其他相关教程

还是简单看看它的参数

1、基本命令

ImageMagick 包括一组命令行工具来操作图片,安装好 ImageMagick 后,终端就可以使用如下命令了。

magick: 创建、编辑图像,转换图像格式,以及调整图像大小、模糊、裁切、除去杂点、抖动 ( dither )、绘图、翻转、合并、重新采样等。
convert: 等同于 magick 命令。
identify: 输出一个或多个图像文件的格式和特征信息,如分辨率、大小、尺寸、色彩空间等。
mogrify: 与 magick 功能一样,不过不需要指定输出文件,自动覆盖原始图像文件。
composite: 将一个图片或多个图片组合成新图片。
montage: 组合多个独立的图像来创建合成图像。每个图像都可以用边框,透明度等特性进行装饰。

compare: 从数学和视觉角度比较源图像与重建图像之间的差异。
display: 在任何 X server 上显示一个图像或图像序列。
animate: 在任何 X server 上显示图像序列。
import: 保存 X server 上的任何可见窗口并把它作为图像文件输出。可以捕捉单个窗口,整个屏幕或屏幕的任意矩形部分。
conjure: 解释并执行 MSL ( Magick Scripting Language ) 写的脚本。
stream: 一个轻量级工具,用于将图像或部分图像的一个或多个像素组件流式传输到存储设备。在处理大图像或原始像素组件时很有用。

2、命令格式

基本命令的使用,遵循 Unix 风格的标准格式:

command [options] input_image output_image

比如我们将一张宽高 300x300 的图片 ic_test.png 转换成 200x200 的ic_test1.jpg,可以这样用

convert -resize 200x200 ic_test.png ic_test1.jpg

-resize 定义图片尺寸,ImageMagick 所有的选项参数都在这个【命令行选项手册】。

但是随着功能的复杂,命令缓慢扩大成了这样的格式:

command [options] image1 [options] image2 [options] output_image

于是上面的命令也可以写成这样

convert ic_test.png -resize 200x200 ic_test1.jpg

笔记:个人建议,如果转换的是一张图片,那么用第一种格式,因为像 -density 等一些选项必须放在 command 与 input_image 之间,所以为了省记都不写错,都写在 command 与 input_image 之间岂不很好。
但是如果是多张图片转换,就需要按第二种格式,正确输出命令选项了。

提示:如果上面的工具命令在计算机上不可以使用,则可以把它们当作 magick 命令的子命令使用,例如

magick identify ic_test.png

3、指定文件格式

默认情况下 ImageMagick 会读取图像中唯一标识格式的签名来确定文件格式,如果没有,则根据文件的扩展名来确定格式,如 image.jpg 被认为 jpeg 格式文件,如果都获取不到,则需要手动指定文件的格式。命令格式为 format:input_or_output_image

输入文件一般情况应该不需要手动指定文件格式,输出文件的时候,png 格式分 png8png24 等格式,如果 png8 格式的文件能够满足需求,指定合理的格式可以缩小文件的大小,示例如下。

convert ic_test.png png8:ic_test_8.png
convert ic_test.png png24:ic_test_24.png

好了基本操作看会了,该实现我的需求了:

首先我有个未知尺寸的图标 ic_old.png 我需要在外面添加一个大改 35 px 的透明边距,最后输出 120x120 的新图标,如下图 test_ic.png 到 testa.png 的处理

使用 ImageMagick 写一个图标批量处理脚本-天真的小窝

思路:首先将 test_ic.png 转大小为 70x70 然后创建一个 120x120 的透明画布再把 test_ic_70x70.png 贴到透明画布的 25h 25w 的位置上

脚本实现:

#!/bin/bash

if [ "$1" = "" ] || [ "$2" = "" ]; then
    echo "待处理图片路径或输出路径未输入!"
    exit 0
fi

old_ic="$1"
log_ic="${old_ic}.deal.png"
ic="$2"

convert $old_ic -resize 70x70 $log_ic && convert -size 120x120 -strip -depth 8 xc:none $log_ic  -geometry +25+25 -composite $ic
rm -rf $log_ic && echo "成功处理:${ic}"

解析:获取两个路径,一个($1)是待处理的图片,还有一个($2)是处理后图片输出路径,然后实现将 test_ic.png 转大小为 70x70 然后创建一个 120x120 的透明画布再把 test_ic_deal.png 贴到透明画布的 25h 25w 的位置上,再将图片输出到 $2 处,最后删除 test_ic_deal.png

好了,实现成功再加一个 for 就可以批量处理了…

话说就是那个搞 RN 的时候用过一个 icon 处理脚本 (https://github.com/bamlab/generator-rn-toolbox),我发现它是处理了 ios 的 icon 和 android 的方型 icon 但是没有处理 android 的圆形图标,我觉得有时间我也许可以帮他优化一下?有兴趣的小伙伴也可以去尝试优化一下?优化后记得通知我去点 Star 哈…