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

Linux ImageMagick:如何在调整大量图像文件大小的同时实现低内存使用率?,linux,image,image-processing,imagemagick,imagemagick-convert,Linux,Image,Image Processing,Imagemagick,Imagemagick Convert,我想调整大量(约5200)图像文件的大小(PPM格式,每个5 MB大小),并使用convert将其保存为PNG格式 短版: $ convert '*.ppm[1280x1280]' pngs/%05d.png convert占用了24GB的内存,尽管我使用了告诉convert连续处理图像文件的语法 长版本: $ convert '*.ppm[1280x1280]' pngs/%05d.png 对于超过25GB的图像数据,我认为我不应该同时处理所有文件。我搜索了有关如何连续处理图像文件的Ima

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

短版:

$ convert '*.ppm[1280x1280]' pngs/%05d.png
convert
占用了24GB的内存,尽管我使用了告诉
convert
连续处理图像文件的语法

长版本:

$ convert '*.ppm[1280x1280]' pngs/%05d.png
对于超过25GB的图像数据,我认为我不应该同时处理所有文件。我搜索了有关如何连续处理图像文件的ImageMagick文档,我:

调整每个图像大小的速度更快,资源消耗更少 阅读:

$convert'*.jpg[120x120]'缩略图%03d.png

还有:

例如,而不是

montage'*.tiff'-geometry 100x100+5+5-第4帧索引.jpg

首先读取所有tiff文件,然后调整其大小。你可以 相反,你应该

montage'*.tiff[100x100]'-几何体100x100+5+5-第4帧索引.jpg

这将读取每个图像并调整其大小,然后再继续 下一张图片。从而大大减少了内存使用,而且可能 当达到内存限制时,防止磁盘交换(抖动)

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

$ convert '*.ppm[1280x1280]' pngs/%05d.png
根据文档,它应该逐个处理每个图像文件:读取、调整大小、写入。我在一台有12个真正内核和24 GB内存的机器上做这件事。但是,在头两分钟内,
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实现同样的效果


谢谢

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

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

  • 添加
    -monitor
    作为第一个命令行参数,以查看有关所发生情况的更多详细信息

  • (可选)添加
    -debug all-log“域:%d+++事件:%e+++函数:%f+++行:%l+++模块:%m+++进程ID:%p+++realCPUtime:%r+++wallclocktime:%t+++用户cputime:%u\n\r“

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

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

    如果你没有找到解决办法,那么

  • …在注册一个用户名
  • …在那里报告您的问题,看看他们是否能帮助您(如果您礼貌地询问,这些人非常友好,反应迅速)

  • 遇到同样的问题,这似乎是因为ImageMagick在/tmp目录中创建临时文件,该目录通常作为tmpfs挂载

    把你的tmp移到别的地方就行了

    例如:

    • 在大型外部驱动器上创建一个“tmp”目录

      mkdir-m777/媒体/巨型设备/tmp

    • 确保权限设置为777

      chmod 777/媒体/大型设备/tmp

    • 作为root用户,将其替换安装到/tmp

      mount-o绑定/媒体/大型设备/tmp/tmp


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

    如果您有12个内核,我将使用GNU并行-类似这样的,工作非常好。由于它一次只处理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个作业。

    如果您尝试类似于
    查找的操作-名称“*.ppm”-执行转换“{}[1280x1280]”pngs/%05d.png\这有用吗
    find-exec
    将列出所有文件,并对每个文件执行参数中给出的命令。@epingle:原则上这是可行的(正如我在问题的最后一部分中所说的)。做那样的事也是我暂时的解决办法。不过,它还必须(应该)与纯ImageMagick一起工作。(请注意,您的特定解决方案不起作用,因为文件计数器
    %05d
    始终为零)。好的,很抱歉,我没有看到您消息的结尾,或者%05d是您的计数器。我将使用netpbm和gnu make(-j12)。如果netpbm适合您,我将复制/粘贴我的工作makefile作为示例。