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

m.d*_*ees 3 linux resize image file imagemagick

情况

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

我尝试过的事情

在使用Windows下的一些工具(Adobe Photoshop和其他工具)之后,我不再愿意在我自己的机器上运行它,因为这使得它在渲染时几乎无法使用.考虑到这个工作的规模,我真的在寻找一些命令行魔术来直接在Linux上运行它,但到目前为止我对ImageMagick的努力并没有给我任何工作,因为我只得到错误.说实话,ImageMagick的文档可以使用一些工作......或者有人应该努力创建一个良好的Web界面来创建这些神秘的图像转换单行之一.

必需的输出格式

我需要将图像大小调整为相同的文件名和格式,以适应特定的最大尺寸,例如1024*1024,这意味着:

  • JPG为2048*1024,质量为75%,JPG为1024*512
  • PNG为1024*2048变为512*1024的PNG

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

谢谢你的帮助!

Hen*_*gen 6

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

要编辑这个bash脚本,我使用nano,如果你没有nano:" apt-get install nano"用于Ubuntu/Debian或" yum install nano"用于CentOS/CloudLinux ..用于其他发行版:使用Google)但你可以自由使用你想要的任何编辑器.

Bash脚本

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

nano -w ~/imgconv.sh
Run Code Online (Sandbox Code Playgroud)

然后用这个内容填写:

#!/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\> {} +
Run Code Online (Sandbox Code Playgroud)

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

cd /var/www/webshop.example.com/public_html/media/
~/imgconv.sh
Run Code Online (Sandbox Code Playgroud)

这应该开始转换过程.

说明

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

find ./ -type f -iname "*.jpeg" -exec <COMMAND> {} +
Run Code Online (Sandbox Code Playgroud)

..然后使用"-exec {} +"参数执行相应的转换作业:

mogrify -verbose -format jpeg -layers Dispose -resize 1024\>x1024\> -quality 75% <### the filename goes here, in this case *.jpeg ###>
Run Code Online (Sandbox Code Playgroud)

如果你正在使用比现在更早的文件并且你想要防止你今天已经转换过的文件,你甚至可以告诉'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\> {} +
Run Code Online (Sandbox Code Playgroud)

性能

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

但无论您将使用何种并行化技术,请确保只在您自己的系统上执行此操作,而不是在生产平台所在的共享磁盘系统上执行此操作,因为获得最大性能会降低硬件或虚拟机管理程序的性能.

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

只需确保通过编写单独的命令将所有文件扩展名彼此分开; 将所有选项堆叠在一起并使用所有图像格式的所有选项进行"mogrify"将无法正常工作.

ImageMagick是右手中强大的工具.

  • 嗯...如果你使用 `find 。-name "*.JPEG" -o -name "*.jpeg"` 你不会找到以 `Jpg` 结尾的文件,所以你最好使用 `-iname "*.JPG"` 并且如果你执行一个 mogrify 进程对于 1500 万个文件中的每一个,当 mogrify 能够接受多个输入文件时,您将在那里停留很多天,因此您真的应该在末尾使用 `+` 而不是 `\;` 以减少创建的进程数量. (2认同)