如何批量调整数百万张图片的大小以适应最大宽度和高度?

How to batch resize millions of images to fit a max width and height?

情况

我正在寻找一种方法来批量调整大约 1500 万张不同文件类型的图像以适应特定的边界框分辨率(在这种情况下,图像不能大于 1024*1024),而无需扭曲图像,从而保持正确的纵横比。所有文件当前都位于我具有 sudo 访问权限的 Linux 服务器上,因此如果我需要安装任何东西,我很高兴。

我尝试过的事情

在尝试了 Windows 下的一些工具(Adobe Photoshop 和其他工具)之后,我不再愿意 运行 在我自己的机器上使用它,因为这会导致它在渲染时几乎无法使用。考虑到这项工作的规模,我真的在寻找一些命令行魔法来直接 运行 它在 Linux 上,但到目前为止我对 ImageMagick 的努力还没有给我任何可以使用的东西除了错误,我一无所获。 老实说,ImageMagick 的文档可能需要一些工作......或者有人应该努力制作一个好的网络界面来创建这些神话般的图像转换单行之一。

要求的输出格式

我需要将图像调整为相同的文件名和适合某个最大尺寸的格式,例如 1024*1024,意思是:

生成的图像不应包含额外的透明像素来填充剩余像素;我只是在寻找一种将图像转换为有限分辨率的方法。

感谢您的帮助!

我发现转换数百万像这样的图像的最佳方法是创建一个简单的 bash 脚本,该脚本开始转换它找到的所有图像,如下面所列:

要编辑此 bash 脚本,如果您没有 nano,我会使用 nano:“apt-get install nano”代表 Ubuntu/Debian 或“yum install nano”代表 CentOS/CloudLinux.. 对于其他发行版:使用 Google) 但您可以自由使用任何您想要的编辑器。

Bash 脚本

首先,通过启动您最喜欢的编辑器(我的 nano)来创建 bash 脚本:

nano -w ~/imgconv.sh

然后填写以下内容:

#!/bin/bash
find ./ -type f -iname "*.jpeg" -exec mogrify -verbose -format jpeg -layers Dispose -resize 1024\>x1024\> -quality 75% {} +
find ./ -type f -iname "*.jpg" -exec mogrify -verbose -format jpg -layers Dispose -resize 1024\>x1024\> -quality 75% {} +
find ./ -type f -iname "*.png" -exec mogrify -verbose -format png -alpha on -layers Dispose -resize 1024\>x1024\> {} +

然后您需要做的就是使用 chmod +x ~/imgconv.sh 和 运行 使它在您想要调整所有子目录中的图像大小的主图像目录中可执行:

cd /var/www/webshop.example.com/public_html/media/
~/imgconv.sh

那应该开始转换过程。

说明

脚本的工作方式是使用 find 查找扩展名为 .jpeg 的任何大写的文件,然后 运行s 命令:

find ./ -type f -iname "*.jpeg" -exec <COMMAND> {} +

.. 然后使用“-exec {} +”参数执行适当的转换作业:

mogrify -verbose -format jpeg -layers Dispose -resize 1024\>x1024\> -quality 75% <### the filename goes here, in this case *.jpeg ###>

如果您正在处理早于今天的文件并且您希望防止重新执行今天已经转换的文件,您甚至可以告诉 'find' 命令仅转换早于今天的文件像这样添加选项 -mtime +1

#!/bin/bash
find ./ -type f -mtime +1 -iname "*.jpeg" -exec mogrify -verbose -format jpeg -layers Dispose -resize 1024\>x1024\> -quality 75% {} +
find ./ -type f -mtime +1 -iname "*.jpg" -exec mogrify -verbose -format jpg -layers Dispose -resize 1024\>x1024\> -quality 75% {} +
find ./ -type f -mtime +1 -iname "*.png" -exec mogrify -verbose -format png -alpha on -layers Dispose -resize 1024\>x1024\> {} +

性能

使用更多内核执行此过程的一种非常简单的方法是通过在每行之后添加 & 将每个作业分叉到后台。另一种方法是使用 GNU Parallel,尤其是使用 -X 参数,因为它将使用你所有的 CPU 内核并更快地完成工作。

但是无论您将使用哪种并行化技术,请确保仅在您自己的系统上执行此操作,而不是在您的生产平台所在的共享磁盘系统上执行,因为追求最佳性能会陷入困境您的硬件或管理程序性能。

这项工作需要一段时间,所以一定要事先设置一个没有 timeout/noop 数据包的屏幕或终端。在我的系统上,它每分钟处理大约 5000 个文件,因此整个工作应该花费不到 50-60 小时......在周末 运行 听起来是个不错的工作。

只需确保通过编写单独的命令将所有文件扩展名彼此分开;将所有选项叠加在一起并'mogrify'对所有图像格式使用所有选项是行不通的。

ImageMagick 是右手的强大工具。