我几乎总是在网站中为我的客户提供一个 PHP 调整大小脚本(使用 GD)。无论我告诉他们多少次在上传之前从他们的数码相机调整他们巨大的 7MP 图像的大小,他们仍然从不这样做。结果是来自服务器的“内存不足”错误,并且图像没有调整大小,因为原始图像在分辨率方面太大了。
有没有更好的方法来调整非常大的图像?是否有提供 API 的服务,我可以通过我的脚本来调整这些大图像的大小?
我几乎总是在网站中为我的客户提供一个 PHP 调整大小脚本(使用 GD)。无论我告诉他们多少次在上传之前从他们的数码相机调整他们巨大的 7MP 图像的大小,他们仍然从不这样做。结果是来自服务器的“内存不足”错误,并且图像没有调整大小,因为原始图像在分辨率方面太大了。
有没有更好的方法来调整非常大的图像?是否有提供 API 的服务,我可以通过我的脚本来调整这些大图像的大小?
您可以调用 Imagemagick 从您的 php 页面调整图片的大小,但是如果您允许系统调用,则存在安全问题
任何 API 都会使用大量内存,您也可以更改 php memory_limit。
如果您的 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.
}
我被这个问题困住了几天(和几夜)。
此外,提供程序的内存限制因人而异。并且更改memory_limit
PHP 在共享服务器上不起作用,提供商通常会限制 ram,即使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设置一个临时目录以模拟ram(种类)
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);
如果存在,这将为您提供二进制文件的路径。
我花了一些时间尝试调试直接使用 GD 的 PHP 代码,但在大图像和似乎有小错误导致 GD 阻塞的图像子集上失败了。
但后来我找到了 phpThumb ( http://phpthumb.sourceforge.net/ ),我再也不会回去了。将两个 PHP 文件添加到我的 web 目录 (phpthumb.class.php
和phpthumb.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
Boom,就像一个魅力,非常快并且对大文件没有问题。此外,它可以使用 GD 或 ImageMagick,具体取决于服务器上可用的内容,因此它相对便携。
只需让他们在上传之前将其调整为更小。MAX_FILE_SIZE
您可以使用外部程序,例如使用convert。
上传它们然后排队调整大小作业怎么样,然后命令行 php 脚本可以拾取和处理(更快并且可以有单独的内存限制和执行时间)