GD (PHP) 因 JPEG 图像大小调整错误 (Laravel Intervention\Image) 而失败,error.log 中没有错误

GD (PHP) failing with bad JPEG image resize (Laravel Intervention\Image), no error in error.log

我在 Windows 和 Ubuntu 开发箱上都是 运行 Apache/PHP 5.6。将 Laravel 5.1 和 Intervention/Image 与 GD 驱动程序一起使用,我正在尝试调整一些相当大的图像 (15-25MB) 的问题是调整大小失败并出现错误 Unable to read image from file (/tmp/phpxxxxxx),但仅在大图像上。 5-10MB 范围内的任何内容都可以调整大小...

我假设它与进程 运行 内存不足有关(因为较小的文件没有问题),但问题是我实际上根本没有收到任何错误消息error.log...

我已经将 php.ini 中的 memory_limit 增加到 2000M 进行测试,但调整大小仍然失败。

控制器中调整图像大小的代码是...

$img = Img::make($file->getRealPath());

通过 Laravel 报告的错误详情如下...

NotReadableException in Decoder.php line 46:
Unable to read image from file (C:\Apache24\htdocs\tmp\php361F.tmp).
in Decoder.php line 46
at Decoder->initFromPath('C:\Apache24\htdocs\tmp\php361F.tmp') in AbstractDecoder.php line 293
at AbstractDecoder->init('C:\Apache24\htdocs\tmp\php361F.tmp') in AbstractDriver.php line 64
at AbstractDriver->init('C:\Apache24\htdocs\tmp\php361F.tmp') in ImageManager.php line 50
at ImageManager->make('C:\Apache24\htdocs\tmp\php361F.tmp') in Facade.php line 216
at Facade::__callStatic('make', array('C:\Apache24\htdocs\tmp\php361F.tmp')) in SubmitPhotoController.php line 97
at Image::make('C:\Apache24\htdocs\tmp\php361F.tmp') in SubmitPhotoController.php line 97
at SubmitPhotoController->store()

我将如何进行进一步的故障排除以找出失败的原因?

备注:

  1. 我减少了 memory_limit 只是为了确保低值在调整大小时会显示错误并且确实如此,所以我认为这不是 PHP 内存问题。
  2. 我确实看到文件出现在 C:\Apache24\htdocs\tmp 中,然后很快就消失了。

编辑:

upload_max_filesize = 2000M
post_max_size = 2000M

编辑 2: 在做了一些测试之后,失败的图像是由我的手机 phone 上的全景功能创建的。即使是更小的文件大小的图像最终也会失败。

GD 需要被告知忽略来自错误 JPEG 的警告,因为显然 GD 不能容忍错误或损坏的 JPEG。这些失败的图像实际上是使用内置全景工具在我的 phone 上创建的。在线下载或通过 photoshop open\saved(修复)的大图像在我开始测试后实际上很好。

ini_set("gd.jpeg_ignore_warning", 1);

and https://bugs.php.net/bug.php?id=39918.

问题源于 Intervention\Image\Gd\Decoder.php

的以下几行
....
$info = @getimagesize($path);
...

// define core
        switch ($info[2]) {
            case IMAGETYPE_PNG:
                $core = @imagecreatefrompng($path);
                break;

            case IMAGETYPE_JPEG:
                $core = @imagecreatefromjpeg($path); //<--------here
                dd($core);
                break;

我可以想象 运行 通过完全忽略警告来解决其他问题。