8

我想调整大量(大约 5200 个)图像文件(PPM 格式,每个大小为 5 MB)并使用convert.

简洁版本:

convertconvert尽管我使用了告诉连续处理图像文件的语法,但会炸毁 24 GB 的内存。

长版:

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

调整读取的每个图像的大小更快且资源消耗更少:

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

此外,教程指出

例如,而不是...

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文档问题,要么我没有正确阅读文档。

怎么了?在调整大量图像文件的大小时,如何实现低内存使用?

顺便说一句:一个快速的解决方案是使用外壳循环文件并convert独立调用每个文件。但我想了解如何使用纯 ImageMagick 实现相同的目标。

谢谢!

4

3 回答 3

6

如果无法直接访问您的系统,那么很难帮助您调试它。

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

  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]'。目的是将您的通配符扩展(或实现相同目的的其他合适方法)限制为仅几个匹配项,而不是所有可能的匹配项。

如果你做'2'。你需要做'3'。否则你会被大量的输出压得喘不过气来。(此外,您的系统似乎无法处理完整的通配符,而无需终止进程......)

如果您没有找到解决方案,那么...

  1. ...在ImageMagick 官方错误报告论坛上注册一个用户名。
  2. ...在那里报告您的问题,看看他们是否可以帮助您(如果您有礼貌地询问,这些人会非常友好且反应迅速)。
于 2012-09-10T21:18:02.700 回答
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 环境变量来执行相同的技巧。

于 2013-09-27T16:50:55.163 回答
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 个作业。

于 2015-10-09T22:52:50.540 回答