为我的服务器上的 GD 库调整太大的图像

Posted

技术标签:

【中文标题】为我的服务器上的 GD 库调整太大的图像【英文标题】:Resize images too large for GD Library on my server 【发布时间】:2009-08-13 15:43:45 【问题描述】:

我几乎总是在网站中为我的客户提供一个 php 调整大小脚本(使用 GD)。无论我告诉他们多少次在上传之前从他们的数码相机调整他们巨大的 7MP 图像的大小,他们仍然从不这样做。结果是来自服务器的“内存不足”错误,并且图像没有调整大小,因为原始图像在分辨率方面太大了。

有没有更好的方法来调整非常大的图像?是否有提供 API 的服务,我可以通过我的脚本来调整这些大图像的大小?

【问题讨论】:

ImageMagick 允许在加载时有效调整大小,请参阅此答案中的更多详细信息:***.com/questions/12661/… 【参考方案1】:

您可以调用 Imagemagick 来调整您的 php 页面中的图片大小,但是如果您允许系统调用,则会出现安全问题

任何 API 都会使用大量内存,您也可以更改 php memory_limit。

【讨论】:

【参考方案2】:

如果您的 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.

【讨论】:

喜欢“警告信息”:)【参考方案3】:

我被这个问题困扰了好几天(几夜)。

此外,提供程序的内存限制因人而异。 并更改memory_limitin PHP 在共享服务器上不起作用,即使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=&lt;tmp_dir&gt; 为 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); 

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

【讨论】:

【参考方案4】:

您可以使用外部程序,例如使用convert。

【讨论】:

【参考方案5】:

上传它们然后排队调整大小作业怎么样,然后命令行 php 脚本可以拾取和处理(更快并且可以有单独的内存限制和执行时间)

【讨论】:

【参考方案6】:

只需让他们在上传之前将其调整为更小。 MAX_FILE_SIZE

【讨论】:

这不会锻炼。图片可能有很多像素(例如 2000x5700),尽管它们非常小(例如 304KB)。【参考方案7】:

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

但后来我找到了 phpThumb (http://phpthumb.sourceforge.net/),我再也不会回去了。将两个 PHP 文件添加到我的 Web 目录(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

Boom,就像一个魅力,非常快,大文件没有问题。此外,它可以使用 GD 或 ImageMagick,具体取决于服务器上可用的内容,因此它相对便携。

【讨论】:

ps。还有 phpThumb.php,你可以链接到它,它会根据查询字符串(和配置文件)中的信息直接创建缩略图,但这不适合我的需要。

以上是关于为我的服务器上的 GD 库调整太大的图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 GD 调整图像大小

PHP GD 方法 imagecopy 比原始图像更大的图像文件

动态GD图像宽度文字

使用 GD 调整图像大小问题

Perl Image Resize 使用 GD 并保持图像质量

使用 PHP GD lib 压缩和调整图像大小不适用于 png 和 jpg 的奇怪结果