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

时间:2016-12-01 00:32:23

标签: linux bash parallel-processing imagemagick xargs

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

find . -type f -name '*.jpg' -exec sh -c '
    orgfile="$0"
    newfile="$(echo "$0" | 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

但另一篇帖子警告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

串行运行的BTW正在使用大约25%的PC资源

4 个答案:

答案 0 :(得分:1)

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

mogrify -unsharp 0x5 -format png *.jpg

你不能在shell中写得更快。对于递归转换使用bash globbing功能:

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

答案 1 :(得分:0)

抱歉Igor,网站上的新手无法在帖子中发布格式化的评论。

Mogrify比xargs略慢但输入更容易。 任务管理器使用Mogrify和更高的CPU显示更高的磁盘利用率,但“更苛刻”(100%下降,xargs一致约50%)

我的结论是,如果只有一些文件使用Mogrify。如果它要整晚运行,请使用xargs作为更酷的PC。

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

find . -type d -exec sh -c '
   subdir="$0"
   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
' {} \;

答案 2 :(得分:0)

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

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应该有帮助。

答案 3 :(得分:0)

如果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 {}