在我的服务器上,如何调整大小超过GD库限制的图像?

6
我经常为客户的网站编写 PHP 调整大小的脚本(使用 GD)。无论我告诉他们多少次在上传前调整他们数码相机拍摄的巨大 7MP 图像,他们仍然从未这样做。结果是服务器出现“内存不足”错误,因为原始图像分辨率太高,所以无法调整大小。

有没有更好的方法来调整真正大的图像?是否有一种服务提供 API,可以通过我的脚本调整这些大型图像?


ImageMagick允许在加载时进行高效的调整大小操作,有关详细信息,请参见此答案:https://dev59.com/d3VD5IYBdhLWcg3wVKEb#4613341 - Steve-o
7个回答

3

如果你的PHP配置中有可用的ImageMagick api - 使用它!ImageMagick不会计入PHP的memory_limit,因此可以处理更大的文件。

如果你真的无法控制服务器,一个快速但非常糟糕的解决方法是 - 在从$_POST获取图像文件后,首先使用以下代码检查其尺寸:

<?php
$image_size = getimagesize("yourfile.jpg")
$mem_usage = $image_size[0] * $image_size[1] * 4 //4 bytes per pixel (RGBA)
if ($mem_usage > $mem_aviable) {
    die ('Please upload smaller pic. I tell you that all the time.  '.
         'Resize yout huge 7MP images from your digital camera '.
         'before uploading them.'); //Better put something more polite here.
}

喜欢那个“警告信息” :) - Erenor Paz

3
你可以从你的php页面调用Imagemagick来调整图片大小,但如果允许系统调用,则存在安全问题。
任何API都会使用大量内存,你也可以更改php的memory_limit。

2
我在这个问题上卡了好几天(夜以继日地卡)。
此外,不同的提供商内存限制也不同。 而且,在PHP中更改memory_limit在共享服务器上无法生效,即使phpinfo()显示你拥有128Mo(例如,1and1将RAM限制为每个进程60Mo)。
但最终我在这里找到了一些相当有效的东西:http://www.imagemagick.org/Usage/files/#massive 它需要imagemagick,但我发现大多数提供商都在他们的服务器上原生提供这个,甚至是共享的。
exec('env MAGICK_TMPDIR=<tmp_dir> nice -5 convert -limit memory 32 -limit map 32 -resize 800x600 huge.jpg reasonable.jpg'); 

如下所述:

  • env MAGICK_TMPDIR=<tmp_dir> 设置一个临时目录供imagemagick模拟内存(有点类似)

  • nice -5 是一个Unix命令,用于改变进程的优先级 (http://en.wikipedia.org/wiki/Nice_(Unix))

  • convert ... 是imagemagick的命令行

真正重要的是 -limit memory 32-limit map 32。这是限制二进制文件使用的内存的方法(此处为32Mo)。您可能需要根据服务器的值来调整这些值(通常PHP在给出致命错误时会告诉您最大分配的内存值。我建议您将此值除以2或4以获得舒适的使用体验)。

我还需要在我的PHP中添加一些其他行来避免一些相关问题:

ignore_user_abort(true); // ignore user abort : let the script finish resizing even if user aborts
set_time_limit(0); // ignore server timeout
putenv('MAGICK_THREAD_LIMIT=1'); // limit the number of thread for the binary. Very important in my case 

希望这些内容能够帮到您...
如何判断您的服务器是否支持convert命令?您可以尝试以下方法(使用PHP):
$out = array();
exec('which convert 2>&1', $out);
print_r($out); 

那将为您提供二进制文件的路径(如果存在)。

1

我曾经花了一些时间尝试调试直接使用GD的PHP代码,但在大型图像和一些似乎有小错误的子集图像上失败了。

但后来我发现了phpThumb(http://phpthumb.sourceforge.net/),我再也不会回去了。在我的Web目录中添加了两个PHP文件(phpthumb.class.phpphpthumb.functions.php)之后,我能够使用以下代码生成缩略图:

include("phpthumb.class.php"); 

// Load data into phpThumb object and set parameters
$phpThumb = new phpThumb();
$phpThumb->setSourceData(file_get_contents($_GET['filename']));
$phpThumb->setParameter('w', $width);  // Set width
$phpThumb->setParameter('h', $height); // Set height
$phpThumb->setParameter('zc', 1);      // Specify zoom-crop (instead of stretch)
$phpThumb->setParameter('q', 100);     // Specify quality

// Generate & output thumbnail
$phpThumb->GenerateThumbnail();        // Generate the thumbnail
$phpThumb->OutputThumbnail();          // Output it to browser
$phpThumb->RenderToFile("$thumbname"); // Output it to file
$phpThumb->purgeTempFiles();           // Clean up

太棒了,运行得非常好,速度很快,处理大文件也没有问题。此外,它可以使用GD或ImageMagick,具体取决于服务器上可用的内容,因此相对来说比较便携。


PS:还有phpThumb.php,您可以链接到它,根据查询字符串(和配置文件)直接创建缩略图,但这不符合我的需求。 - Magnus

1

您可以通过外部程序进行 shell 操作,例如使用 convert


1

上传它们,然后将调整大小的作业排队,命令行 PHP 脚本可以接着处理(更快且可以有单独的内存限制和执行时间)。


1

在上传之前让他们把文件大小调整小一点。MAX_FILE_SIZE


这行不通。图像可能有很多像素(如2000x5700),尽管它们非常小(如304KB)。 - Christian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接