有效检测损坏的jpeg文件


Efficiently detect corrupted jpeg file?

是否有一种有效的方法来检测jpeg文件是否已损坏?

背景信息:
 解决方案需要在php脚本中工作
 jpeg文件在磁盘上
 手动检查没有选项(用户上传的数据)

我知道imagecreatefromjpeg(string $filename);可以做到。但它做得很慢。

有人知道更快/更有效的解决方案吗?

从命令行,您可以使用jpeginfo来确定jpeg文件是否正常。

$jpeginfo-c test.jpeg

test.jpeg 260 x 264 24位JFIF N 15332[确定]

从php调用jpeginfo应该很简单。

我最简单(也是最快)的解决方案:


function jpeg_file_is_complete($path) {
    if (!is_resource($file = fopen($path, 'rb'))) {
        return FALSE;
    }
    // check for the existence of the EOI segment header at the end of the file
    if (0 !== fseek($file, -2, SEEK_END) || "'xFF'xD9" !== fread($file, 2)) {
        fclose($file);
        return FALSE;
    }
    fclose($file);
    return TRUE;
}
function jpeg_file_is_corrupted($path) {
    return !jpeg_file_is_complete($path);
}

注意:这只检测损坏的文件结构,但不检测损坏的图像数据。

FYI-我使用了上面的方法(jpeg_file_is_complete)来测试我知道已损坏的JPEG(例如,当我在浏览器中加载它们时,底部是灰色的,即图像被"剪切")。无论如何,当我对该图像进行上述测试时,它并没有检测到它已损坏。

到目前为止,使用imagecreatefromjpeg()是可行的,但速度不是很快。我发现使用jpeginfo可以很好地检测这些类型的损坏图像,并且比imagecreatefromjpeg更快(我在PHP中使用microtime()运行了一个基准测试)。

请尝试

<?php
$img = $_GET['img'];
$str_exec = 'jpeginfo -c /chroot/home/www/html/media/'.$img;
$result = exec($str_exec);
if(strpos($result, 'ERROR'))
{
    echo 'ERROR';
}
else
{
    echo 'OK';
}
?>

只是一个小提示-如何获得适用于Windows(64位)的jpeginfo作者的github上没有win32/win64二进制文件,但你可以这样做:

1) 从此存档中获取jpeginfo.exe:https://github.com/MoserMichael/cstuff/raw/master/img-archive/img-archive.zip

2) 从此存档中获取cygwin1.dll:ftp://mirror.internode.on.net/pub/cygwin/x86/release/cygwin64/cygwin64-2.6.0-1.tar.xz

从命令行测试它是否有效:jpeginfo --help。如果有信息的话,它会很好地工作。

如何测试jpeginfo输出

如果文件正常,Warning: unknown JFIF revision number 2.01 1280 x 720 24bit JFIF N 122550 [WARNING]返回0,但它不仅在不正常时返回1,而且在发现不理解的内容时也返回1。然后它会生成这样的消息:

1328 x 2048 24bit JFIF N 1310080 Premature end of JPEG file [WARNING]

在损坏的文件上,它返回1和消息如下:

CCD_13

因此,您可能希望测试实际输出,而不仅仅是返回代码。

您还可以尝试基于MD5生成文件哈希,并在各个步骤中将其用作校验和来验证JPEG数据。例如,从文件读取之后,然后在传输之后,等等。

解决方案:

我找到了我需要的完美工具:

http://www.thomasbarker.co.uk/2011/05/29/corrupt-jpeg-checkertool-for-finding-corrupt-jpeg-image-files/

递归地搜索目录并找到任何损坏的JPEGS。看起来你也可以使用任意多的CPU。

为我工作。

我有另一个简单的getimagesize()解决方案

if(!getimagesize($image_url)) echo 'Image is corrupt or not readable';