我写了一个简单的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处理有效?
这是原始上传文件的一部分。
根据要求,我使用imagecreatefromjpeg
添加了我打开文件的方式。它不是一个权限问题,因为脚本在90%的时间内工作正常,就在它遇到失败的图像时。
edit2 :我原本以为它可能是并发问题,因为我每分钟都会通过cron运行脚本,但FTP上传不受服务器控制,所以他们异步运行。因此,脚本可能正在上传时正确访问该文件,但我检查过并非如此,因为我上面写的上传文件在开始时已损坏。
edit3 :建议的imagecolorat不是解决方案(至少不适用于所有情况):我刚发现一张混乱的图片会通过那个测试。 jpeginfo
说:损坏的JPEG数据:标记为0xd9之前的10839个无关字节
答案 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 中发布的示例仍然通过了此测试。