源图像损坏时,imagecopy失败

时间:2016-07-26 12:28:59

标签: php gd

我写了一个简单的PHP脚本来向网络摄像头JPG文件添加其他信息。它添加了一些文本的页眉和页脚。为此,我使用此信息创建一个新图像,然后使用imagecopy复制原始JPG。一切正常。

网络摄像头与互联网的wifi连接很差,因此很少发生通过FTP上传的JPG文件部分或损坏:我可以使用GIMP或其他图像软件打开它,我看到它有一些缺少的信息底部。发生这种情况时,上述imagecopy似乎无法复制图像数据,目标图像仍为空白(对于图像区域)。

我尝试了我发现的所有内容,以检查原始JPG是否有效:

// Check image
if (exif_imagetype($last) != IMAGETYPE_JPEG) // Not a valid jpeg
    continue;
$details = getimagesize($last);
if ($details === FALSE) // Not a valid mage
    continue;
$im = imagecreatefromjpeg($last);

但所有测试都通过了。我还补充道:

if (imagecopy($dest_image, $im, 0, $top_banner_height+1, 0, 0, $img_width, $img_heigth) === FALSE) {
   imagedestroy($im);
   imagedestroy($dest_image);
   continue;
}

但我仍然无法捕获未终止的上传。如何检查图像是否对GD处理有效?

编辑:这是源图像在GIMP中的显示方式: image showing the error

这是原始上传文件的一部分。

根据要求,我使用imagecreatefromjpeg添加了我打开文件的方式。它不是一个权限问题,因为脚本在90%的时间内工作正常,就在它遇到失败的图像时。

edit2 :我原本以为它可能是并发问题,因为我每分钟都会通过cron运行脚本,但FTP上传不受服务器控制,所以他们异步运行。因此,脚本可能正在上传时正确访问该文件,但我检查过并非如此,因为我上面写的上传文件在开始时已损坏。

edit3 :建议的imagecolorat不是解决方案(至少不适用于所有情况):我刚发现一张混乱的图片会通过那个测试。 jpeginfo说:损坏的JPEG数据:标记为0xd9之前的10839个无关字节 sample failing imagecolorat test

1 个答案:

答案 0 :(得分:1)

感谢所有的建议,但最后我发现了另一种可能的方式。

如上所述,在other answers中,命令行工具jpeginfo -c filename检查图像是否是有效的jpeg,打印警告或错误(以及返回码!= 0)。所以它到目前为止是最精确的解决方案,但涉及外部命令。

在PHP方面,似乎不是完美检查,同时对方Imagick::valid也没有对完整图像执行有效性检查。

very same page那里有另一个建议的解决方案:

// check for the existence of the EOI segment header at the end of the file
$file = fopen($image_file, "r");
if (0 !== fseek($file, -2, SEEK_END) || "\xFF\xD9" !== fread($file, 2)) {
    // jpeg is not valid
    fclose($file);
    return FALSE;
}

效果很好,但仅适用于未完成的图像(第一种情况)。 edit 3 中发布的示例仍然通过了此测试。