当前位置: 首页 > 知识库问答 >
问题:

加载大图像时达到硬内存限制,加载时可能下载样本?

笪煌
2023-03-14

我需要从潜在的巨大图像(10000 x 10000)生成小缩略图。我正在使用运行在谷歌应用程序引擎中的ImageMagick和PHP。我的GAE的硬盘内存限制为512 MB。

我一直在尝试阅读imagemagick php扩展的文档,但是文档很薄。我发现这篇文章很好,维护人员给出了答案,并试图修改他们的代码。我试图设置资源区域,以便将大于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");
}

超过512 MB和514 MB的硬内存限制...

在Android设备上,当从磁盘加载位图时,有一个选项可以在将其加载到内存时对其进行下采样。这使我能够将图像的较小版本加载到内存中,并避免庞大文件破坏一切的问题。

ImageMagick中有类似的东西吗?我看到ImageMagick::setSamplingFactors(),但留档根本没有解释参数,所以我不确定如何使用它。

我如何从一个巨大的图像生成一个微小的缩略图,而不会达到我的硬内存限制在谷歌应用程序引擎?

共有1个答案

秦毅
2023-03-14

如果您正在收缩JPEG图像,那么Imagemagick支持加载收缩。例如,这里有一个10kx10k像素的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。

-define jpeg:size=400x400向jpeg加载程序提示您希望图像至少为400x400像素,因此(在本例中)在加载过程中,图像大小将为1/8。您需要加载提示大小至少比最终输出大小大2倍,以避免出现别名。

您可以使用setOption从imagick进行设置。

不幸的是,许多装载机不支持随载收缩。巴布亚新几内亚尤其糟糕:

$ /usr/bin/time -f %M:%e \
    convert wtc.png -resize 200x200 x.jpg
828376:5.62

830MB和5.6s。

您可以考虑其他调整大小的程序。

$ /usr/bin/time -f %M:%e \
    vipsthumbnail wtc.png --size 200x200 -o x.jpg
58780:2.29

60MB和2.3s用于相同的PNG文件。质量与Imagemagick相同。

它也有一个PHP绑定--您可以编写例如:

$image = Vips\Image::thumbnail('somefile.jpg', 200);
$image->writeToFile('tiny.jpg');
 类似资料:
  • 据我所知,您可以通过以下方式使用PIL获取图像大小 但是,我希望获得图像的宽度和高度,而不必将图像加载到内存中。可能吗?我只做图像大小的统计,不关心图像内容。我只是想让我的处理速度更快。

  • 问题内容: 我有一个React应用,可以调用我的API,该API返回URL列表以用作imy图像src。 我用来显示图像加载时的加载微调组件。 我有一个变量来确定图像是否正在加载。 我无法弄清楚如何停止显示正在加载的微调器,并在它们全部加载后显示图像。 这是我的代码: Photos.jsx Photo.jsx 我尝试将我的最后一项用于,但是它永远不会被调用,因为由于仍然显示了微调框,所以它从未设置为

  • 问题内容: 问题描述: 我正在创建一个滚动的带有缩略图的文章列表,该列表由我的SQLite数据库填充。通常,它运行缓慢,但速度较慢: 图像加载非常缓慢…我想使用“ 通用图像加载器 ”将图像缓存在设备上,如果您已经查看过图像(或者至少接近该图像,那会使它们看起来只是滚动到视图中) )。但是- 当您向上/向下拖动时,没有任何图像,然后在3-5秒后,图像开始弹出(就像重新下载它们一样) 我正在动态更改缩

  • 问题内容: 我需要做的事情很简单,但是(对我来说)很难做到: 使用 javascript ,给定图像名称,即“ image01.jpg”,我需要检查该图像是否存在于某个文件夹或路径(本地或网络)中。如果该文件夹下不存在该图像,则需要检查另一个文件夹中是否存在同一图像。 例如,使用伪代码 您建议采用哪种方法?我尝试先使用ajax来实现此目的,然后使用javascript的Image()来实现,但是在

  • 问题内容: 我想从我的应用程序中的URL加载图像,因此我首先尝试使用Objective-C,但是它可以正常工作,但是对于Swift,我遇到了编译错误: ‘imageWithData’不可用:使用对象构造’UIImage(data :)’ 我的功能: 在Objective-C中: 有人可以解释一下为什么Swift无法使用它,以及如何解决该问题。 问题答案: Xcode 8或更高版本•Swift 3或

  • 我想从我的应用程序中的URL加载一个图像,所以我首先尝试使用Objective-C,它成功了,但是,使用Swift,我有一个编译错误: “imageWithData”不可用:使用对象构造“UIImage(数据:)” 我的职能: 在目标C中: 有人能给我解释一下为什么不能与Swift一起工作,以及我如何解决这个问题。