使用ImageMagick(不增加内存)调整jpg大小时如何防止oom ?



在使用ImageMagick调整jpg大小时,似乎忽略了-limit选项。

下面的命令使用docker来模拟在有限的空闲内存(100MB)的机器上运行ImageMagick: ImageMagick命令通过-limit memory 5MiB传递4958 × 6198 JPEG(原始文件大小:5.5MB)来调整大小。

结果是ImageMagick被容器的OOM Killer杀死,这意味着ImageMagick试图分配超过~100MB的内存,而不是保持在它被指示的~5MB的限制内。如果您增加(或删除)docker run上的--memory 100m标志,该命令将成功:

# Download a 5.5MB JPEG (4958 × 6198)
curl 'https://images.unsplash.com/photo-1534970028765-38ce47ef7d8d?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=trail-5yOnGsKUNGw-unsplash.jpg' 
-o 5500kb-image.jpg
docker run --memory 100m 
-v $(pwd):/imgs 
dpokidov/imagemagick 
/imgs/5500kb-image.jpg 
-debug All -limit memory 5MiB -limit map 10MiB -resize 400 
/imgs/5500kb-image-resized.jpg

我怎么能内存绑定ImageMagick时调整jpeg大小?

我觉得你的参数顺序不对。

如果你在linux上,/usr/bin/time是非常方便的测量峰值内存使用。你正在运行这个命令:

$ /usr/bin/time -f %M:%e 
convert 
5500kb-image.jpg 
-limit memory 5MiB -limit map 10MiB 
-resize 400 5500kb-image-resized.jpg
346060:2.37

ie。350mb内存,2.37s CPU时间

如果你把限制放在前面,你会看到:

$ /usr/bin/time -f %M:%e 
convert 
-limit memory 5MiB -limit map 10MiB 
5500kb-image.jpg -resize 400 5500kb-image-resized.jpg
105468:2.64

现在峰值只有105mb,运行时间差不多。您需要在加载图像之前设置限制。

正如Mark所说,vipsthumbnail相当快,内存消耗更少。我明白了:

$ /usr/bin/time -f %M:%e 
vipsthumbnail 5500kb-image.jpg --size 400 -o 5500kb-image-resized.jpg
133676:0.28

130mb, 0.28s。

这仍然相当高。您的图像是渐进式JPG—在缩略开始之前,这些图像必须完全加载到内存中,并且不可能利用jpeg shrink-on-load之类的东西。

如果我你的图像转换为一个普通的jpeg,我明白了:

$ /usr/bin/time -f %M:%e 
vipsthumbnail 5500kb-image-regular.jpg --size 400 -o 5500kb-image-resized.jpg
40200:0.09

40mb和0.1s的CPU。

vipsthumbnail可以用少量内存调整非常大的图像,例如:

$ vipsheader st-francis.jpg 
st-francis.jpg: 30000x26319 uchar, 3 bands, srgb, jpegload
$ /usr/bin/time -f %M:%e 
vipsthumbnail st-francis.jpg --size 400 -o 5500kb-image-resized.jpg
49692:2.52

50mb, 2.5s。

4958×6198图像有30,729,684像素。每个将有一个R, G和B通道制作92,189,052个样本。由于每个样本通常以16位(2字节)的分辨率存储,因此您需要180+MB的RAM来保存它。以及用于输出图像的空间。

你通常会发现libvips更节省内存,如果这是你最关心的。这里的示例显示了相对内存需求以及如何度量它们。

相关内容

  • 没有找到相关文章

最新更新