在 Linux 或者 MacOS 的命令行里做图片转换,用到的命令叫做 convert,是属于 ImageMagick 套件里的一个工具。这篇文章整理的内容包括转换图片格式,调整图片分辨率大小,裁剪图片这几个常用功能。另外文章里用到的 identify 命令也属于 ImageMagick 套件,作用是查看图片文件的属性。

如果系统没有 convert 命令的话,安装 ImageMagick 套件就可以了。一般软件源里都会有这个包,例如 Ubuntu 里 sudo apt install imagemagick,MacOS 里 brew install imagemagick 就能成功安装了。

PNG 转换为 JPG 格式

convert original.png original.jpg

使用 identify original.jpg 查看输出结果是

original.jpg JPEG 1280x720 1280x720+0+0 8-bit sRGB 227KB 0.000u 0:00.009

后面的例子主要以这张大小为 1280×720 的 original.jpg 作为原始的输入图片。

调整图片大小

convert original.jpg -resize 900x800 out1.jpg

900x800的比例与原图不同,800 会被忽略,得到的 out1.jpg 的分辨率是 900x506,与原图比例相同。

$ identify out1.jpg
out1.jpg JPEG 900x506 900x506+0+0 8-bit sRGB 129KB 0.000u 0:00.000

实际上这条转换命令只写要输出的图片宽度,不写高度,结果是一样的。

$ convert original.jpg -resize 900 out2.jpg
$ md5sum out1.jpg
a860476ae63fc2b99b80efb4b8504fd3
$ md5sum out2.jpg
a860476ae63fc2b99b80efb4b8504fd3

也可以只写高度,不写宽度,会按指定高度,保持原图比例输出。

$ convert original.jpg -resize x400 out2.1.jpg
$ identify out2.1.jpg
out2.1.jpg JPEG 711x400 711x400+0+0 8-bit sRGB 84.5KB 0.000u 0:00.000

如果要强制得到 900x800 分辨率的结果,在输出尺寸参数后面加 ! 感叹号。

$ convert original.jpg -resize 900x800! out3.jpg
$ identify out3.jpg
out3.jpg JPEG 900x800 900x800+0+0 8-bit sRGB 191KB 0.000u 0:00.000

百分比尺寸

convert original.jpg -resize 50% out4.jpg

查看转换结果

$ identify out4.jpg
out4.jpg JPEG 640x360 640x360+0+0 8-bit sRGB 69.8KB 0.000u 0:00.000

上例中只给了一个 50% 参数,原图的宽和高都变为原来的一半输出。

如果给宽和高都指定百分比,那么图片就会按照指定百分比输出,即使没有加 ! 感叹号,也不会保持原图比例。

$ convert original.jpg -resize 50%x10% out4.1.jpg
$ identify out4.1.jpg
out4.1.jpg JPEG 640x72 640x72+0+0 8-bit sRGB 18.5KB 0.000u 0:00.010

注意,如果想要宽 600 高按原图 50% 输出,不要用 600x50% 这样的参数。文章最后会解释为什么。

裁剪图片

convert original.jpg -crop 900x300+0+0 out5.jpg

得到的图片大小是 900x300。命令中的 +0+0 是指相对图片最左上角在 X 轴和 Y 轴上的偏移量。

$ identify out5.jpg
out5.jpg JPEG 900x300 900x300+0+0 8-bit sRGB 47.6KB 0.000u 0:00.000

例如 convert original.jpg -crop 900x300+100+200 out6.jpg 输出的图片还是 900x300 的大小,但是截取的位置在 X 轴上偏移 100 像素,在 Y 轴上偏移 200 像素。

$ identify out6.jpg
out6.jpg JPEG 900x300 900x300+0+0 8-bit sRGB 79.7KB 0.000u 0:00.000
$ md5sum out5.jpg
5885d81091662d31dca79f6ba24729c9  out5.jpg
$ convert md5sum out6.jpg
e1c31403a5308013e627ef335a5f756f  out6.jpg

如果只写第一个尺寸 900,并且在 Y 轴的偏移量为 0,那么输出图片的高度与原图一直。在宽 900 参数后面仍然必须加上 x,否则命令格式错误。类似的,也可以只写高度,例如 x610+0+0 这样的参数。

$ convert original.jpg -crop 900+0+0 out7.jpg
convert-im6.q16: invalid argument for option `-crop': 900+0+0 @ error/convert.c/ConvertImageCommand/1184.
$ convert original.jpg -crop 900x+0+0 out7.jpg
$ identify out6.jpg
out6.jpg JPEG 900x720 900x720+0+0 8-bit sRGB 153KB 0.000u 0:00.000

如果只写第一个尺寸,Y 轴偏移量不为 0,那么输出图片的高度是原图高度减去偏移量。

$ convert original.jpg -crop 900x+10+30 out8.jpg
$ identify out7.jpg
out7.jpg JPEG 900x690 900x690+0+0 8-bit sRGB 160KB 0.000u 0:00.000

百分比尺寸

裁剪图片的尺寸参数,也支持使用百分比。

$ convert original.jpg -crop 50%x+0+0 out8.jpg
$ identify out8.jpg
out8.jpg JPEG 640x360 640x360+0+0 8-bit sRGB 42.3KB 0.000u 0:00.000

$ convert original.jpg -crop 50%x60%+0+0 out10.jpg
$ identify out10.jpg
out10.jpg JPEG 640x432 640x432+0+0 8-bit sRGB 56.4KB 0.000u 0:00.000

$ convert original.jpg -crop 900x60%+0+0 out11.jpg
$ identify out11.jpg
out11.jpg JPEG 1280x432 1280x432+0+0 8-bit sRGB 124KB 0.000u 0:00.000

百分比尺寸的“误用”

上面的最后一个例子值得注意,其中的参数 900 是被忽略的,得到的结果是 1280x432,高度是原图的 60%,宽度与原图一致,其实 900x60% 是被解释为原图宽度的 900%,高度的 60%,而在裁剪图片时,超过原图的值是没有意义的。在这个例子中,900x60%+0+0x60%+0+0 是相当的。

$ convert original.jpg -crop x60%+0+0 out12.jpg
$ identify out11.jpg
out11.jpg JPEG 1280x432 1280x432+0+0 8-bit sRGB 124KB 0.000u 0:00.000

$ md5sum out11.jpg
c21f42de3a7feebbdd950d6bb21a44d6  out11.jpg
$ md5sum out12.jpg
c21f42de3a7feebbdd950d6bb21a44d6  out12.jpg

在调整图片大小的最后提到,不要用 600x50% 这样的参数,因为这个参数会被解释为原图宽度的 600%,高度的 50%,在 99.99% 的场景下,这不会是你想要的结果。

$ convert original.jpg -resize 600x50% out999.jpg
$ identify out999.jpg
out999.jpg JPEG 7680x360 7680x360+0+0 8-bit sRGB 472KB 0.000u 0:00.009

结果的宽度是原图的 6 倍,而不是 600 像素。