Php 带有';示例:偏移量';通过只读取部分像素来读取大图像

Php 带有';示例:偏移量';通过只读取部分像素来读取大图像,php,imagemagick,php-7,imagick,Php,Imagemagick,Php 7,Imagick,我有一些非常大的图像(10000 x 10000),我想为它们创建小缩略图。不幸的是,我无法使用imagick(ImageMagickPHP)将它们读入内存,因为我的内存不足 在Android设备上,从磁盘加载位图时,会出现一个错误。这使我能够将图像的较小版本加载到内存中(只需每2或每4个像素读取一次,等等),并避免了巨大文件破坏一切的问题 我在想办法用imagick做类似的事情。我找到了setOption()函数,它允许我向imagemagick工具发送类似于命令行参数的参数 其中一个选项是s

我有一些非常大的图像(10000 x 10000),我想为它们创建小缩略图。不幸的是,我无法使用imagick(ImageMagickPHP)将它们读入内存,因为我的内存不足

在Android设备上,从磁盘加载位图时,会出现一个错误。这使我能够将图像的较小版本加载到内存中(只需每2或每4个像素读取一次,等等),并避免了巨大文件破坏一切的问题

我在想办法用imagick做类似的事情。我找到了
setOption()
函数,它允许我向imagemagick工具发送类似于命令行参数的参数

其中一个选项是
sample:offset
,它说我可以给它一个。其中一个可能的几何定义是给它一个百分比,如
25%
,表示高度和宽度都按指定的百分比缩放。

当我尝试加载一个
png
10988 x 5782
并使用以下代码时,png仍然以完整大小加载到内存中(在我的本地主机上它几乎无法处理,但在服务器上内存不足):

我是否正确使用了
setOption()
?这是要设置的正确选项吗?我需要一个不同的值吗

以下是我尝试过的一些其他格式,它们似乎也没有任何效果:

$im->setOption('sample:offset', '25%+0+0');
$im->setOption('sample:offset', '700x700'); // to scale it down to 700 pixels by 700 pixels
$im->setOption('sample:offset', '700x700+0+0');

我已经能够使用
$im->setOption('jpeg:size'、$smallwidth.x'.$smallheight')实现一个解决方案,其中包含
jpg
文件
但我需要能够处理
png
和其他图像类型。

加载时收缩是libjpeg加载库的一项功能。这不是ImageMagick的功能

这可能是因为JPEG图像的编码方式:它们被分割成8x8像素块,JPEG对该块的平均值加上一组DCT系数进行编码。解码时,可以获得8x8平均值,然后仅重建足够的块以生成4x4像素版本(例如)。这就是为什么libjpeg提供1/8、1/4和1/2大小的解码。ImageMagick使用
jpeg:size
选项公开此库功能

PNG图像不是这样编码的。他们使用一个简单的预测器,并用zlib将预测错误编码为单个巨大的数据流。您无法解码图像的一部分,也无法以较低的分辨率解码

处理大型PNG图像的唯一方法是流式处理。您解码(例如)10个像素扫描线,处理它们,写入输出,然后解码下一组扫描线。ImageMagick不能以这种方式工作,因此您所需要的是不可能的


因此,我认为您需要一个流式图像处理库,例如。

避免使用Imagick,并通过直接调用ImageMagick的命令行生成缩略图,这是一个明智的做法。我是Imagick的维护者,知道什么时候不使用它是件好事。
$im->setOption('sample:offset', '25%+0+0');
$im->setOption('sample:offset', '700x700'); // to scale it down to 700 pixels by 700 pixels
$im->setOption('sample:offset', '700x700+0+0');