2016-07-26 84 views
1

我编写了一个简单的PHP脚本来为网络摄像头JPG文件添加附加信息。它添加了一些文本的页眉和页脚。为此,我使用此信息创建一个新图像,然后使用imagecopy将原始JPG复制到内部。它一切正常。当源图像损坏时,imagecopy失败

网络摄像头与互联网有很差的无线连接,所以很少发生通过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数据:标志之前10839个的外来字节0xd9 sample failing imagecolorat test

+0

很可能图像文件本身并没有损坏,只是有很多未填充(如此默认值)的空白像素。权限问题或访问问题也可能会干扰文件输入。你可以编辑你的问题,并发布你如何访问文件,以及文件属性(如Linux)。请记住,您的“登录用户”与计算机中的“php用户”不同。 – Bonatti

+0

我编辑了附加信息。但我100%肯定这不是一个许可问题,该文件正确打开90%的时间 – Maxxer

+1

你可以检查图像文件的最终字节是否为'EOI'(图像的结尾:'FF D9')。如果没有,图像“可能有问题”。您可以重写该文件的最后一个字节,然后运行该脚本。 – Bonatti

回答

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; 
} 

的伟大工程,但仅限于未完成的图像(第一种情况)。举例编辑3仍然通过这个测试。