如何使用 Image Magic 跨多个子目录并行批量转换 1000 张图像

How to batch convert 1000's of images across multiple sub directories in parallel using Image Magic

我有 ~100 个子目录,每个子目录有 ~1000 个文件 我想使用 BASH for Win10 下的 Image MagickJPG 转换为 PNG,即 LINUX script。我的脚本很慢,我可以加快速度吗?

find . -type f -name '*.jpg' -exec sh -c '
    orgfile="[=10=]"
    newfile="$(echo "[=10=]" | sed 's/.jpg/.png/')"
    echo $orgfile $newfile
    convert $orgfile -unsharp 0x5 $newfile
    rm $orgfile
' {} \;

我喜欢循环过程,因为转换是许多过程中的第一个,因此输入和输出名称可以重复使用。然而,它的速度很慢并且有回声用于反馈(更改为每个目录?)

在相关的post中给出了以下解决方案

# Runs these conversions serially
ls *.NEF | sed 's#.NEF##' | xargs -I^ convert ^.NEF ^.jpg
# Runs these conversions with 8 different processes
ls *.NEF | sed 's#.NEF##' | xargs -P8 -I^ convert ^.NEF ^.jpg

但是另一个 post 警告说 parallel processing 可能会降低系统速度

/media/ramdisk/img$ time for f in *.bmp; do echo $f ${f%bmp}png; done | xargs -n 2 -P 2 convert -auto-level

我想我在高级 BASH 脚本和并行处理中迷路了,我不知道 xargs

顺便说一句 运行 连续使用大约 25% 的 PC 资源

使用 imagemagick 的内联批处理,称为 mogrify

mogrify -unsharp 0x5 -format png *.jpg

您无法在 shell 中写得更快。对于递归转换,使用 bash globbing 特性:

shopt -s globstar
mogrify -unsharp 0x5 -format png **/*.jpg

抱歉 Igor,网站新手无法 post 对您的 post 进行格式化评论。

Mogrify 比 xargs 稍慢,但更易于输入。 任务管理器显示 Mogrify 和更高的磁盘利用率 CPU 但 "spikier"(100% 下降,xargs 一致约 50%)

我的结论是,如果只有一些文件,请使用 Mogrify。如果要 运行 通宵使用 xargs 以获得更酷的 PC。

我的时间测试是针对一个子目录。

find . -type d -exec sh -c '
   subdir="[=10=]"
   echo $subdir

   #test mogrify
   time mogrify -unsharp 0x5 -format png "${subdir}/*.jpg"
   #1011.65user 30.07system 7:47.85elapsed 222%CPU

   for f in "${subdir}/*.jpg"; do echo $f ${f%jpg}png; done| time xargs -n 2 -P 8 -i convert ifile/ '{}' -unsharp 0x5 ofile/ '{}'
   #991.95user 29.35system 7:22.46elapsed 230%CPU
' {} \;

我的方法略有不同。我没有使用 xargs,而是收集了所有需要在单个文本文件中处理的文件。随机播放它 (split.exe) 以平均分配工作,将它分成 8 个相等的部分,因为我有 8 个核心 cpu (shuf.exe) 和 运行 它是并行的。这是 windows 批次:

dir /s/b *.jpg > allfiles
shuf allfiles -o allfiles
split -n l/8 allfiles
for %%i in (xaa xab xac xad xae xaf xag xah) do (
    start /separate /low /min magick mogrify -verbose -format png @%%i 
)
:loop
tasklist.exe | grep -i "magick.exe\|mogrify.exe" > nul
echo %time% %errorlevel% processing...
if %errorlevel%==0 goto loop

del xa?

还有一个循环检查是否一切都已完成。虽然 split 和 grep 可以由 unxUtils 提供,但 shuf 仅在 cygwin 中可用。我跳过了删除旧文件的部分,但 this 应该有所帮助。

如果 mogrify 仅使用 1 CPU 您可以使用 GNU Parallel 进行并行化:

parallel mogrify -unsharp 0x5 -format png ::: *.jpg

或者如果文件列表对于 shell 来说太长了:

ls | parallel mogrify -unsharp 0x5 -format png {} 

多个子目录:

find subdir1 subdir2 -name '*.jpg' | parallel mogrify -unsharp 0x5 -format png {}