【问题标题】:ImageMagick: how to achieve low memory usage while resizing a large number of image files?ImageMagick:如何在调整大量图像文件大小的同时实现低内存使用?
【发布时间】:2012-09-03 08:56:42
【问题描述】:

我想调整大量(大约 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 中存在错误、文档存在问题,要么我没有正确阅读文档。

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

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

谢谢!

【问题讨论】:

  • 如果您尝试类似find . -name "*.ppm" -exec convert '{}[1280x1280]' pngs/%05d.png \; 这样的方法有效吗? find -exec 将列出所有文件,并为每个文件执行参数中给出的命令。
  • @epingle:原则上这是可行的(正如我在问题的最后一部分中所说的那样)。做这样的事情也是我的临时解决方案。尽管如此,它还必须(应该)与纯 ImageMagick 一起工作。 (请注意,您的特定解决方案将不起作用,因为文件计数器 %05d 将始终为零)。
  • 好吧,抱歉,我没有看到你的消息的结尾,或者 %05d 是你的计数器
  • 我会使用 netpbm 和 gnu make (-j12)。如果您可以使用 netpbm,我将复制/粘贴我的工作 makefile 作为示例。

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


【解决方案1】:

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

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

  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. ...在the official ImageMagick bug report forum注册一个用户名。
  2. ...在那里报告您的问题,看看他们是否可以帮助您(如果您有礼貌地询问,这些人会非常友好且反应迅速)。

【讨论】:

    【解决方案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 环境变量来做同样的事情。

    【讨论】:

      【解决方案3】:

      如果你有 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 个作业。

      【讨论】:

        猜你喜欢
        • 2011-05-17
        • 1970-01-01
        • 2020-01-27
        • 1970-01-01
        • 2016-03-20
        • 2014-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多