在Linux上使用ImageMagick命令行进行批量转换时,结果损坏

这是我的IM命令:

/usr/bin/convert 'src.tif' -limit memory 0 -limit map 0 -limit file 0 -alpha transparent -clip -alpha opaque -resize 800x600 'end.png' 2>&1 

所以这将通过剪切文件中给出的path来删除我的TIFF的白色背景。 它将被resize并保存为透明的PNG。

我没有从运行这个IM的错误。

但是,如果我用PHP运行这个命令来执行它约13000个文件 – 我有时会得到这些错误:

 sh: line 1: 25065 Killed /usr/bin/convert \ 'public_html/source_files/XXXX123/XXXX123/XXXX123.tif' \ -limit memory 0 -limit map 0 -limit file 0 -alpha transparent \ -clip -alpha opaque -resize 800x600 \ 'public_html/converted/XXXX123/XXXX123/XXXX123_web.png' 2>&1 sh: line 1: 25702 Killed /usr/bin/convert \ 'public_html/source_files/XXXX123/XXXX123/XXXX123.tif' \ -limit memory 0 -limit map 0 -limit file 0 -alpha transparent \ -clip -alpha opaque -resize 800x600 \ 'public_html/converted/XXXX123/XXXX123/XXXX123_web.png' 2>&1 

但是更大的问题是:有些照片坏了。 下面是左边的一个“坏”图像,右边是一个“好”的图像(ondrag /在黑暗的背景上,你会发现问题更好):

在手动运行命令结果是好的。 只有运行这个PHP循环脚本才会提供破坏的结果。 ( PHP循环脚本 )

我这样运行脚本: php55 run.php 。 使用find作为shell脚本的简单循环提供了相同的结果。

所以我search了IM语音服务器,并在两台configuration不同的机器上运行这个程序(Debian Wheezy,Ubuntu Server 14.04)

注意/编辑1:使用相同的文件在terminal运行命令提供了一个完美的结果。

编辑2: 在这里添加示例TIFF文件

我不确定这是否是答案。 现在这是纯粹的猜测。 所以这里…

通过设置限制为0值,您基本上告诉ImageMagick: “您的资源不受限制,您不需要关心任何限制。

  • 如果没有设置任何限制? 从命令中删除所有-limit ... 0部分。 在这种情况下,ImageMagick将使用其内置的默认值或其他定义的设置(可能包含在IM安装的policy.xml文件中,或通过各种环境变量 )。 您可以使用以下命令查询系统的当前限制:

     identify -list resource 

    在我的系统上,我得到这些值:

     File Area Memory Map Disk Thread Throttle Time --------------------------------------------------------------------------- 192 4.295GB 2GiB 4GiB unlimited 1 0 unlimited 
  • 如果你确实将这些限制设置为一个合理的值,那么这与系统真正可用的资源相匹配呢? 假设您具有:8 GB RAM,50 GB可用磁盘空间和大量磁盘卷上的空闲inode 。 然后尝试像这样设置: -limit disk 10GB -limit memory 3GB -limit map 6GB


ImageMagick资源管理

对于所有的处理和中间步骤,ImageMagick需要访问一个中间像素缓存内存/存储器 ,然后才能传递最终结果。

像素缓存存储的这种需求可以通过不同的资源来满足:

  • 堆内存,
  • 匿名内存映射,
  • 基于磁盘的内存映射,
  • 直接磁盘。

ImageMagick逐步使用所有这些资源:

  • 一旦堆内存耗尽,它将像素存储在匿名映射中。
  • 一旦匿名内存映射耗尽,它会在磁盘上创建像素缓存并尝试对其进行内存映射。
  • 一旦内存映射内存耗尽,它只是使用标准的磁盘I / O。

磁盘存储价格便宜,但速度也很慢:比内存慢3个数量级(一千次)。 通过使用内存映射到基于磁盘的缓存,可以获得一些速度提升(最多5次)。

ImageMagick意识到各种方法来控制这些资源的数量:

  1. 内置的默认值 。 这些限制是:768个文件,3GB图像区域,1.5GiB内存,3GiB内存映像和18.45EB磁盘空间。

  2. policy.xml配置文件 。 请查看您自己的policy.xml文件中的内容。 使用convert -list policy首先找到这个文件的位置。 然后使用cat /some/path/policy.xml来查看它的内容。 (该文件使用XML语法,不要忘记: <!---->中的任何内容都是注释!)它还包含解释各种细节的注释。 policy.xml可以定义比可用限制资源更多的东西。 如果在这里定义的话, policy.xml中的设置优先于内置的默认值。

  3. 环境变量 。 以下是可限制IM资源的环境变量列表: MAGICK_AREA_LIMIT (映像区域限制), MAGICK_DISK_LIMIT (磁盘空间限制), MAGICK_FILE_LIMIT (打开文件限制的最大数量), MAGICK_MEMORY_LIMIT (堆内存限制), MAGICK_MAP_LIMIT (内存映射限制), MAGICK_THREAD_LIMIT (最大线程数限制)和MAGICK_TIME_LIMIT (以秒为单位的最大消耗时间)。 这些环境变量(如果已设置)优先于policy.xml配置文件。

  4. 在命令行上限制-limit <name> <value>设置 。 以下<names>被识别:

    • width (图像的最大宽度)。 当超出限制时,抛出异常并停止处理。
    • height (图像的最大高度)。 当超出限制时,抛出异常并停止处理。
    • area (任何单个图像驻留在像素高速缓存中的最大字节数)。 当超过限制时,自动缓存到磁盘(可能内存映射)设置。
    • memory (从匿名映射内存或堆分配给像素缓存的最大内存)。
    • map (分配给像素高速缓存的内存映射的最大量)。
    • disk (像素缓存允许使用的最大磁盘空间量)。 当超过限制时, 不会创建像素缓存,并引发致命的异常。
    • files (打开的像素缓存文件的最大数量)。 当超过限制时,缓存到磁盘的所有后续像素都将关闭,并按需重新打开。
    • thread (可以并行的最大线程数)。
    • time (进程允许执行的最大时间,以秒为单位)。 当这个限制被执行时,抛出异常并且处理停止。

    命令行上的-limit设置将优先并覆盖所有其他设置。