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

标签 php linux shell imagemagick batch-processing

这是我的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

因此,这将通过剪切文件中给定的路径来删除TIFF的白色背景。它将调整大小并另存为透明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

但更大的问题是:有些图片坏了。下面是左侧的“坏”图像,右侧是“好”图像(拖动/在深色背景上会更好地看到问题):


手动运行命令后,结果正常。仅在运行此PHP循环脚本时,才会提供错误的结果。 (PHP loop script)

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

因此,我在IM语篇服务器中进行搜索,询问,并在两台具有不同分布的计算机上运行此过程(Debian Wheezy,Ubuntu Server 14.04)

注意/编辑1:在终端中使用相同文件运行命令可以得到理想的结果。

编辑2:添加了示例TIFF文件here

最佳答案

我不确定这是否是答案。就目前而言,这纯粹是猜测。所以这里...

通过将限制设置为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。

  • 磁盘存储很便宜,但也很慢:它比内存慢了三个数量级(一千倍)。通过使用内存映射到基于磁盘的缓存,可以提高一些速度(最多5倍)。

    ImageMagick知道控制这些资源数量的各种方法:
  • 内置默认值。这些限制是:768个文件,3GB的图像区域,1.5GiB内存,3GiB内存映射和18.45EB的磁盘空间。
  • policy.xml配置文件。请查找您自己的policy.xml文件中的内容。首先使用convert -list policy查找该文件的位置。然后使用cat /some/path/policy.xml查看其内容。 (该文件使用XML语法。不要忘记:<!---->中包含的任何内容都是注释!)它还包含注释,解释了各种详细信息。 policy.xml不仅可以定义可用的限制资源,还可以定义更多内容。如果在其中定义了默认值,则policy.xml中的设置优先于内置默认值。
  • 环境变量。这是可以限制IM资源的环境变量列表:MAGICK_AREA_LIMIT(图像区域限制),MAGICK_DISK_LIMIT(磁盘空间限制),MAGICK_FILE_LIMIT(打开文件的最大数量限制),MAGICK_MEMORY_LIMIT(堆内存限制),MAGICK_MAP_LIMIT(内存映射限制) ),MAGICK_THREAD_LIMIT(最大线程数限制)和MAGICK_TIME_LIMIT(最大经过时间,以秒为单位)。如果设置了这些环境变量,它们将优先于policy.xml配置文件。
  • 命令行上的
  • -limit <name> <value>设置。可以识别以下<names>:
  • width(图像的最大宽度)。当超过限制时,将引发异常并停止处理。
  • height(图像的最大高度)。当超过限制时,将引发异常并停止处理。
  • area(任何单个图像驻留在像素高速缓存中的最大字节数)。当超过限制时,将自动自动缓存到磁盘(可能是内存映射)。
  • memory(从匿名映射内存或堆分配给像素缓存的最大内存)。
  • map(分配给像素缓存的内存映射的最大数量)。
  • disk(像素缓存允许使用的最大磁盘空间量)。超过限制时,不会创建像素缓存,并且会引发致命异常。
  • files(打开的像素缓存文件的最大数量)。超过限制时,将关闭所有随后缓存到磁盘的像素,并根据需要重新打开。
  • thread(可以并行运行的最大线程数)。
  • time(允许一个进程执行的最长时间(以秒为单位)。超过此限制后,将引发异常并停止处理。

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

    关于php - 在Linux上使用ImageMagick命令行进行批量转换时,结果损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27917851/

    相关文章:

    php - Paypal 错误错误代码: 580022 paypal adaptive parallel payment

    php - 在 Controller Laravel 中复制数据

    php - 获取包含字母和非字母的字符串中最后出现的字母

    linux - 电子邮件中的 df nice 输出格式

    linux - 我们如何获得 linux 上的非系统用户列表?

    shell - arduino yun与USB声卡获取文件数

    php - 在 Woocommerce 中添加自定义订单状态 "Shipped"

    php - Apache 安装和运行 php 文件

    linux - 强制 SNMP 将数字视为整数

    linux - 如何在 shell 中重复破折号(连字符)