imagecreatefromjpeg 正在静默终止脚本
像我之前的许多人一样,我正在编写一个 PHP 脚本来执行一些图像缩略图。 该脚本已获得 WOMM(在我的机器上运行)认证,但是当我将其移动到我的主机(1&1 Basic)时,出现了一个问题:无法处理超过特定文件大小的图像。 我已将所有操作移至文件系统,以确保这不是一些潜在的 POST
问题。 以下是相关代码:
function cropAndResizeImage( $imageLocation )
{
//
// Just to be certain
//
ini_set('display_errors','on');
error_reporting(E_ALL);
ini_set('memory_limit','128M');
ini_set('max_execution_time','300');
$image_info = getimagesize($imageLocation);
$image_width = $image_info[0];
$image_height = $image_info[1];
$image_type = $image_info[2];
switch ( $image_type )
{
// snip...
case IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($imageLocation);
break;
default:
break;
}
// snip...
}
使用我神奇的 println
调试能力,我已经能够确定 imagecreatefromjpeg
没有返回; 事实上,脚本到达目的地时就完全停止了。 一些事实:
- 这与文件大小相关。 1MB 以下的图像看起来没问题(经过抽查),但 3MB 左右的图像就很糟糕。 但不知道精确的截止点是什么。
- 这不是由于服务器超时;而是由于服务器超时。
wget
在 3MB 图像上返回 <1 秒,在“适当小”图像上返回时间明显更长(表明不处理大图像)。 - 在函数调用前添加
@
前缀来抑制错误没有效果。 这与脚本没有抛出错误的事实非常匹配,它只是默默地终止此函数调用。
如果我不得不猜测,可能有一些我不知道(或无法访问)的 GD 参数限制了 1&1 的服务器上的输入文件大小 - 配置变量猜测是因为它立即崩溃,并且不会(启发式地)对图像进行任何实际加载或计算。
有什么建议么? 谢谢您的帮助。
更新(由@Darryl的评论提供):调用phpinfo
表明 PHP 正在正确更新 max_execution_time
和 memory_limit
变量。 这并不一定意味着这些资源正在被分配,只是它们看起来正在按预期运行。
更新 2:根据 Google 的一些参考资料,我尝试优化 JPEG(质量从 3MB 降低到 200KB),但没有成功,所以这不是图像文件大小问题。 然后我尝试减少原始 3888x2592 图像的像素数,第一个成功的尺寸是 1400x2592(1401x 和 1402x 都会导致半解析和指示“格式错误的 JPEG”的错误,除非整个图像都没有多大意义)未加载)。 通过进一步缩小到 1300x2592,我可以实例化我实际正在寻找的 400x300 缩略图; 在 1400x2592 分辨率下,我用来处理该任务的 imagecreatetruecolor
调用会以与 imagecreatefromjpeg
相同的方式静默失败。
至于为什么会这样,我有点不确定。 1400 * 2592 == 3.5MB 没有什么特别意义,但我不得不想象这是 GD + PHP 将处理的像素数量的限制。
Like so many before me, I'm writing a PHP script to do some image thumbnailing. The script has earned WOMM (works on my machine) certification, but when I move it to my host (1&1 Basic), there's an issue: images above a certain filesize cannot be processed. I've moved all operations to the filesystem, to be certain it's not some latent POST
issue. Here's the relevant code:
function cropAndResizeImage( $imageLocation )
{
//
// Just to be certain
//
ini_set('display_errors','on');
error_reporting(E_ALL);
ini_set('memory_limit','128M');
ini_set('max_execution_time','300');
$image_info = getimagesize($imageLocation);
$image_width = $image_info[0];
$image_height = $image_info[1];
$image_type = $image_info[2];
switch ( $image_type )
{
// snip...
case IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($imageLocation);
break;
default:
break;
}
// snip...
}
Using my mystical powers of println
debugging, I've been able to determine that imagecreatefromjpeg
is not returning; in fact, the script halts completely when it gets to it. Some facts:
- This is correlated to filesize. Images under 1MB appear to be fine (spot-checked), but images around 3MB barf. No clue what the precise cutoff is, though.
- This is not due to server timeouts;
wget
returns in <1s on 3MB images, significantly longer on "appropriately small" images (indicating no processing of large images). - Prefixing the function call with
@
to suppress errors has no effect. This matches well with the fact that the script is not throwing an error, it's simply silently terminating upon this function call.
If I had to guess, there may be some GD parameter that I don't know about (or have access to) that limits input file sizes on 1&1's servers — the config variable guess is due to the fact that it barfs immediately, and doesn't appear (heuristically) to do any actual loading of or computations on the image.
Any suggestions? Thanks for the help.
Update (courtesy @Darryl's comments): calls to phpinfo
indicate that PHP is updating the max_execution_time
and memory_limit
variables correctly. This doesn't necessarily mean that these resources are being allocated, simply that they appear to be functioning as expected.
Update 2: following some references from The Google, I tried optimizing the JPEG (reduced in quality from 3MB to 200KB) with no luck, so it's not an image filesize issue. I then tried reducing the number of pixels of the original 3888x2592 image, and the first successful size is 1400x2592 (1401x and 1402x both result in half-parses and errors indicating "malformed JPEG", which doesn't make much sense unless the entire image isn't being loaded). By reducing further to 1300x2592, I can instantiate the 400x300 thumbnail image that I'm actually looking for; at 1400x2592, the imagecreatetruecolor
call I'm using to take care of that task fails silently in the same manner as imagecreatefromjpeg
.
As to why this is, I'm a little uncertain. 1400 * 2592 == 3.5MB gives nothing particularly meaningful, but I have to imagine this is a limit on the number of pixels GD + PHP will process.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有关 php 网站上的内存使用情况,请参阅此说明。
*“使用 imagecreatefromjpeg() 加载图像所需的内存是图像尺寸和图像位深度乘以开销的函数。
可以通过以下公式计算:
字节数 = 宽度 * 高度 * 每像素字节数 * 开销忽悠因素”*
Please see this note regarding memory usage on the php website.
*"The memory required to load an image using imagecreatefromjpeg() is a function of the image's dimensions and the images's bit depth, multipled by an overhead.
It can calculated from this formula:
Num bytes = Width * Height * Bytes per pixel * Overhead fudge factor"*
我猜测 1&1 不允许您更改脚本
memory_limit
或max_execution_time
,因此它可能会耗尽内存。 您是否尝试过运行 phpinfo() 来查看限制是什么?I'm guessing 1&1 doesn't allow you to change scripts
memory_limit
ormax_execution_time
, so it's probably running out of memory. Have you tried runningphpinfo()
to see what the limits are?