ImageMagick:如何在调整大量图像文件的同时实现低内存使用?

时间:2012-09-10 13:18:25

标签: linux image image-processing imagemagick imagemagick-convert

我想调整大量(约5200)图像文件(PPM格式,每个大小为5 MB)的大小,并使用convert将其保存为PNG格式。

简短版:

convert会释放24 GB的内存,尽管我使用的语法告诉convert连续处理图像文件。

长版:

关于超过25 GB的图像数据,我认为我不应该同时处理所有文件。我搜索了有关如何连续处理图像文件的ImageMagick文档和found

  

调整每个图像的速度更快,资源更少   读:

     

$ convert '*.jpg[120x120]' thumbnail%03d.png

另外,the tutorial states

  

例如,而不是......

     

montage '*.tiff' -geometry 100x100+5+5 -frame 4 index.jpg

     

首先读取所有tiff文件,然后调整它们的大小。您可以   而是做...

     

montage '*.tiff[100x100]' -geometry 100x100+5+5 -frame 4 index.jpg

     

这会在继续之前读取每个图像并调整它们的大小   下一张图片。导致内存使用量大大减少,并且可能   当达到内存限制时,防止磁盘交换(抖动)。

因此,这就是我正在做的事情:

$ convert '*.ppm[1280x1280]' pngs/%05d.png

根据文档,它应该逐个处理每个图像文件:读取,调整大小,写入。我在具有12个真实内核和24 GB RAM的机器上执行此操作。但是,在前两分钟内,convert进程的内存使用量增长到大约96%。它会停留在那里一段时间。 CPU使用率最高。再过一段时间,过程就会消失,只是说:

  

终止

此时,尚未生成任何输出文件。我在Ubuntu 10.04上,convert --version说:

Version: ImageMagick 6.5.7-8 2012-08-17 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2009 ImageMagick Studio LLC
Features: OpenMP 

看起来convert尝试在开始转换之前读取所有数据。因此,convert中存在错误,文档存在问题,或者我没有正确阅读文档。

有什么问题?如何在调整大量图像文件的同时实现低内存使用?

BTW:一个快速的解决方案是使用shell循环遍历文件,并为每个文件独立调用convert。但我想了解如何使用纯ImageMagick实现相同目的。

谢谢!

3 个答案:

答案 0 :(得分:5)

如果没有直接访问您的系统,很难帮您调试。

但你可以做三件事来帮助自己缩小这个问题:

  1. 添加-monitor作为第一个命令行参数,以查看有关正在发生的事情的更多详细信息。

  2. (可选)添加-debug all -log "domain: %d +++ event: %e +++ function: %f +++ line: %l +++ module: %m +++ processID: %p +++ realCPUtime: %r +++ wallclocktime: %t +++ userCPUtime: %u \n\r"

  3. 暂时不要使用'* .ppm [1280x1280]'作为参数,而是使用'a * .ppm [1280x1280]'代替。目的是将通配符扩展(或其他一些合适的方法实现相同)限制为仅几个匹配,而不是所有可能的匹配。

  4. 如果你做'2'你需要做'3'否则你将被大量的输出所淹没。 (此外,您的系统似乎无法处理完整的通配符而无需终止进程...)

    如果找不到解决方案,那么......

    1. ...在the official ImageMagick bug report forum注册用户名。
    2. ...在那里报告你的问题,看看他们是否可以帮助你(如果你礼貌地问这些家伙是相当友好和敏感的。)

答案 1 :(得分:2)

得到了同样的问题,似乎是因为ImageMagick将临时文件创建到/ tmp目录,它通常作为tmpfs挂载。

将你的tmp移到其他地方。

例如:

  • 在大型外置硬盘上创建“tmp”目录

    mkdir -m777 /media/huge_device/tmp

  • 确保权限设置为777

    chmod 777 /media/huge_device/tmp

  • 以root身份安装,替换为/ tmp

    mount -o bind /media/huge_device/tmp /tmp

注意:应该可以使用TMP环境变量来执行相同的操作。

答案 2 :(得分:1)

如果你有12个内核,我会选择GNU Parallel - 就像这样,效果非常好。由于它一次只能处理12个图像,同时仍保留输出文件编号,因此它只使用最少的RAM。

scene=0
for f in *.ppm; do
   echo "$f" $scene
   ((scene++))
done | parallel -j 12 --colsep ' ' --eta convert {1}[1280x1280] -scene {2} pngs/%05d.png

备注

-scene可让您设置场景计数器,该计数器位于%05d部分。

--eta预测你的工作何时完成(预计抵达时间)。

-j 12一次并行运行12个作业。