GD (PHP)失败与坏的JPEG图像大小调整(Laravel干预图像),error.log中没有错误


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

我在Windows和Ubuntu开发盒上运行Apache/PHP 5.6。使用Laravel 5.1和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:在做了一些测试之后,出现问题的照片是我手机上的全景功能拍摄的。即使是更小的文件大小的图像也会失败。

需要告诉GD忽略来自不良JPEG的警告,因为显然GD对错误或损坏的JPEG不是很宽容。这些失败的图片实际上是在我的手机上使用内置全景工具创建的。在我开始测试后,在线下载或通过photoshop(修复)打开保存的大型图像实际上都很好。

ini_set("gd.jpeg_ignore_warning", 1);

https://stackoverflow.com/a/3901885/895810和https://bugs.php.net/bug.php?id=39918.

问题源于以下几行干预'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;

我可以想象如果完全忽略警告会遇到其他问题。