Эффективно обнаружить поврежденный файл jpeg?

Есть ли эффективный способ обнаружения, если файл jpeg поврежден?

Фоновая информация:
решения должны работать из PHP-скрипта
файлы jpeg находятся на диске
ручная проверка не является опцией (загруженные пользователем данные)

Я знаю, что imagecreatefromjpeg(string $filename); может сделать это. Но это довольно медленно.

Кто-нибудь знает более быстрые / более эффективные решения?

Related of "Эффективно обнаружить поврежденный файл jpeg?"

Из командной строки вы можете использовать jpeginfo, чтобы узнать, есть ли файл jpeg в порядке или нет.

$ jpeginfo -c test.jpeg

test.jpeg 260 x 264 24bit JFIF N 15332 [OK]

Должно быть тривиально вызывать jpeginfo из php.

Мое самое простое (и самое быстрое) решение:

 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 также позволяет обнаруживать эти типы поврежденных изображений и является FASTER, чем 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'; } ?> 

Просто небольшое примечание – как получить jpeginfo для Windows (64 бит)? Нет никаких бинарных файлов win32 / win64 в github автора, но вы можете сделать это:

1) grab jpeginfo.exe из этого архива: https://github.com/MoserMichael/cstuff/raw/master/img-archive/img-archive.zip

2) grab cygwin1.dll из этого архива: ftp://mirror.internode.on.net/pub/cygwin/x86/release/cygwin64/cygwin64-2.6.0-1.tar.xz

Проверьте его из командной строки, если он работает: jpeginfo --help . Если есть информация, она работает нормально.

Как проверить выход jpeginfo?

jpeginfo возвращает 0, если файл в порядке, но он возвращает 1 не только тогда, когда это не так, но и когда он обнаружил что-то, что он не понимает. Затем он генерирует следующее сообщение:

Warning: unknown JFIF revision number 2.01 1280 x 720 24bit JFIF N 122550 [WARNING]

В поврежденных файлах он возвращает 1 и следующее сообщение:

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

Поэтому вы можете проверить фактический вывод не только кода возврата.

Вы также можете попытаться создать хэш файла на основе MD5 и использовать его в качестве контрольной суммы для проверки данных JPEG на разных этапах. Например, после чтения из файла, затем после передачи и т. Д.

Решение:

Я нашел идеальный инструмент для того, что мне нужно:

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

Искает рекурсивно через каталог и находит поврежденные JPEGS. Похоже, вы можете использовать столько процессоров, сколько хотите.

Работал для меня.

У меня есть другое решение с просто getimagesize ()

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