考虑以下简单的PHP脚本:
<?php
print memory_get_usage()."<br />";
print ini_get("memory_limit")."<br />";
$file = imagecreatefromjpeg("image.jpg");
?>
输出如下:
109848
120M
Fatal error: Out of memory (allocated 63700992) (tried to allocate 23040 bytes) in /homepages/13/d444038670/htdocs/bilderarchiv/test.php on line 4
我试图阅读的图片是一张大图片。但是,第二行指出memory_limit为 120 MB,但脚本在分配大约 64 MB 时死亡。这怎么可能?该脚本在另一个提供程序上完美运行,尽管那里的memory_limit也是 120M。
您的内存不足,但有一个解决方案。
尝试在两台服务器上运行以下命令,以确定每个图像像素需要多少内存:
<?php
$mem0 = memory_get_usage(true);
$megapix = imagecreatetruecolor(1000,1000);
$mem1 = memory_get_usage(true);
$memdif = $mem1 - $mem0;
$perpixel = $memdif / (1000 * 1000);
echo "<pre>1 million pixel memory test
before imagecreate: $mem0
after imagecreate: $mem1
image memory used: $memdif
bytes per pixel: $perpixel";
?>
我得到了这些结果:
1 million pixel memory test (Linux)
before imagecreate: 524288
after imagecreate: 5505024
image memory used: 4980736
bytes per pixel: 4.980736
1 million pixel memory test (Windows)
before imagecreate: 262144
after imagecreate: 5505024
image memory used: 5242880
bytes per pixel: 5.24288
以每像素 5 字节计算,您的 5760x3240 图像将需要 89MB。
要查看 imagecreatefromjpeg 是否需要超出图像所需的 89MB 的大量临时内存,请在加载图像后将memory_get_usage
与memory_get_peak_usage
进行比较。在我的测试中,没有显着的。
(我认为旧版本的GD使用了4个字节。
接下来,找出你真正有多少内存:
<?php
echo 'memory_limit ??? ', ini_get('memory_limit'), '<br>';
$megs = Array();
for ( $i=0; $i < 1000; ++$i ) { // try up to 1000MB
$megs[] = str_repeat('*', 1048000);
$mb= round(memory_get_usage(true) / 1024/1024);
echo "$mb ";
flush();
ob_flush();
}
?>
如果您根本没有输出,则可能存在您无法禁用的缓冲,因此只需在for
循环中尝试不同的上限,直到找到仍然有效的最大上限。
一个解决方案
我很久以前就放弃了GD来缩小大型jpeg图像,而是使用ImageMagick。如果你从 PHP 中执行它,它是一个单独的进程,所以 PHP 内存限制不再适用。当然,最终会有内存限制,但您可以告诉 ImageMagick 要使用的最大内存。
(我也得到了比GD更好的图像质量。