破損したjpegファイルを効率的に検出しますか?
-
10-07-2019 - |
質問
jpegファイルが破損しているかどうかを検出する効率的な方法はありますか?
背景情報:
 ソリューションは、PHPスクリプト内から動作する必要があります
  jpegファイルはディスクにあります
 手動チェックはオプションではありません(ユーザーがアップロードしたデータ)
imagecreatefromjpeg(string $ filename);
でできることを知っています。しかし、そうするのは非常に遅いです。
より速く/より効率的なソリューションを知っている人はいますか
解決
コマンドラインからjpeginfoを使用して、jpegファイルが正常かどうかを確認できます。
$ jpeginfo -c test.jpeg
test.jpeg 260 x 264 24ビットJFIF N 15332 [OK]
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用のjpeginfo(64ビット)の入手方法 著者の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出力のテスト方法
jpeginfo
は、ファイルに問題がない場合は0を返しますが、ファイルが正しくない場合だけでなく、理解できないものを見つけた場合にも1を返します。次に、次のようなメッセージを生成します。
警告:不明なJFIFリビジョン番号2.01 1280 x 720 24ビットJFIF N 122550 [警告]
破損したファイルでは1を返し、次のようなメッセージを返します。
1328 x 2048 24ビットJFIF N 1310080 JPEGファイルの早期終了[警告]
したがって、戻りコードだけでなく、実際の出力をテストすることもできます。
MD5に基づいてファイルハッシュを生成し、それをチェックサムとして使用して、さまざまな手順でJPEGデータを検証することもできます。たとえば、ファイルから読み取った後、転送後など。
解決策:
必要なものに最適なツールを見つけました:
ディレクトリを再帰的に検索し、破損したJPEGを見つけます。好きなだけCPUを使用できるようです。
私のために働いた。
単純にgetimagesize()を使用する他のソリューションがあります
if(!getimagesize($image_url)) echo 'Image is corrupt or not readable';