Есть ли эффективный способ обнаружения, если файл jpeg поврежден?
Фоновая информация:
решения должны работать из PHP-скрипта
файлы jpeg находятся на диске
ручная проверка не является опцией (загруженные пользователем данные)
Я знаю, что imagecreatefromjpeg(string $filename);
может сделать это. Но это довольно медленно.
Кто-нибудь знает более быстрые / более эффективные решения?
Из командной строки вы можете использовать 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 на разных этапах. Например, после чтения из файла, затем после передачи и т. Д.
Решение:
Я нашел идеальный инструмент для того, что мне нужно:
Искает рекурсивно через каталог и находит поврежденные JPEGS. Похоже, вы можете использовать столько процессоров, сколько хотите.
Работал для меня.
У меня есть другое решение с просто getimagesize ()
if(!getimagesize($image_url)) echo 'Image is corrupt or not readable';