google-app-engine - 加载大图像时达到硬内存限制,加载时可能会下采样?
问题描述
我需要从可能巨大的图像(10,000 x 10,000)中生成小缩略图。我正在使用在 Google App Engine 中运行的 ImageMagick 和 PHP。我的 GAE 的硬内存限制为 512 MB。
我一直在尝试阅读 imagemagick php 扩展的文档,但是文档很薄。我发现这个 SO 帖子得到了维护者的回答,并试图调整他们的代码。我试图设置资源区域,以便将大于 2000x2000 像素的图像换出到磁盘而不是保存在内存中,但要么我误解了代码,要么我做错了什么。我的 GAE 仍然崩溃,说我已经填满了内存。
try {
Imagick::setResourceLimit(Imagick::RESOURCETYPE_AREA, 2000 * 2000);
Imagick::setResourceLimit(Imagick::RESOURCETYPE_DISK, 1024*1024*1024*2);
$im = new \Imagick($path);
// ...
} catch (\Exception $e) {
error_log("Exception: " . $e->getMessage() . "\n");
}
Exceeded hard memory limit of 512 MB with 514 MB...
在 Android 设备上,当从磁盘加载位图时,可以选择在将其加载到内存时对其进行下采样。这使我可以将较小版本的图像加载到内存中,并避免巨大文件破坏所有内容的问题。
ImageMagick 中有类似的东西吗?我看到了ImageMagick::setSamplingFactors()但文档根本没有解释参数,所以我不确定如何使用它。
如何在不达到 Google App Engine 的硬内存限制的情况下从一张巨大的图像生成一个小缩略图?
解决方案
如果您正在缩小 JPEG 图像,那么 imagemagick 支持加载时缩小。例如,这是一个 10k x 10k 像素的 JPEG 图像,其尺寸缩小到 200x200。
$ /usr/bin/time -f %M:%e \
convert wtc.jpg -resize 200x200 x.jpg
713340:2.98
那是 720MB 的峰值内存使用和将近 3 秒的 CPU 时间。现在试试这个:
$ /usr/bin/time -f %M:%e \
convert -define jpeg:size=400x400 wtc.jpg -resize 200x200 x.jpg
35952:0.32
低至 35MB 的内存和 300ms 的 CPU。
提示 JPEG 加载器-define jpeg:size=400x400
您需要至少 400x400 像素的图像,因此(在这种情况下)在加载期间,它将以 1/8 大小获取。您需要加载提示大小至少比最终输出大小大 2 倍以避免混叠。
您可以使用 imagick 进行设置setOption
。
不幸的是,许多加载器不支持加载收缩。PNG尤其糟糕:
$ /usr/bin/time -f %M:%e \
convert wtc.png -resize 200x200 x.jpg
828376:5.62
830MB 和 5.6 秒。
您可以考虑其他调整大小的程序。vipsthumbnail
对于几乎所有文件格式来说都是快速且低内存的,例如:
$ /usr/bin/time -f %M:%e \
vipsthumbnail wtc.png --size 200x200 -o x.jpg
58780:2.29
同一个 PNG 文件需要 60MB 和 2.3 秒。质量与 imagemagick 相同。
它也有一个PHP 绑定——你可以这样写:
$image = Vips\Image::thumbnail('somefile.jpg', 200);
$image->writeToFile('tiny.jpg');
推荐阅读
- php - PHP 执行查询返回错误的输出
- bash - 剪切命令不重定向
- apache-spark - 火花流:执行每日聚合
- c++ - 通过 DirectX12 工具包进行挑选
- android - Parse-SDK-Android:parse:1.24.0 有修复吗
- python - 相对 import_module 不知道包含包的名称
- outlook-addin - 调用方法需要提升权限:'mailbox.getUserIdentityToken'
- jekyll - kernel_require.rb 无法加载此类文件 jekyll
- dotnetnuke - 将 DNN (DotNetNuke) 迁移到 Godaddy Plesk
- acumatica - 如何使用 put 在 acumatica 中上传照片