グラフィックファイルの破損のスキャンを自動化する


27

グラフィックファイル(特にJPEG、GIF、PNG)の破損を(できれば自動化された方法で)チェックする方法を知っている人はいますか?


説明:

数日前、コマンドが正しく機能せず、事実上スペース不足のFAT32ボリュームから数千のグラフィックファイルが削除されました。私はいくつかの異なるファイル/写真回復プログラムを使用しましたが、当然、回復できる量には制限があります(幸いなことに、ボリュームには8KBクラスターがあり、いくらか役立ちます)。

とにかく、断片化された大きなファイルの一部は現在破損しています。それらの一部は、実際のファイルでさえありません(リカバリソフトウェアは、現在上書きされているディレクトリエントリによってポイントされたクラスターを単にダンプしました)が、その他は断片化のために壊れています。

さらに、一部の画像形式では画像の小さいバージョンがサムネイルとして埋め込まれるため、実際のファイル(フルサイズで表示したときの画像)が破損している可能性があるため、サムネイルの破損のスキャンは信頼できません。


次に例を示します。

これが2つ目です。破損しているため、何も表示されません。

破損した画像

(3番目のもの、正しいヘッダーさえ持っていないためアップロードしません!)


視覚的な破損を意味するのでしょうか?私はこれが大好きだ...最後に、壊れたjpgのために私の漫画本のサムネイルを目撃するのをやめることができました。
-Shinrai

視覚的または構造的。これを行うと思われるアプリを1つ見つけましたが、ヘッダーのない多くのファイルを見逃していました
Synetech

ああ、そのようなことは私にも起こりませんでした。はい、お願いします...これはどこかに存在する必要がありますか?
新井

1
このような壊れたファイルの1つ以上の例をアップロードし、質問でそれらにリンクできますか?
slhck

@Shinraiは、多くの画像形式には画像に埋め込まれた個別のサムネイルバージョンが含まれているため、サムネイルを調べることは信頼できません。そのため、サムネイルが正常に表示されていても、開いたときに画像が破損することがあります。
Synetech

回答:


12

同じ質問に答えようとしているときにこれに出くわしたので、見つけた別の素晴らしいソリューションを追加します。

悪いペギー

アプリケーションのスクリーンショット

使用法
メニューから選択File > Scanし、ファイルダイアログを使用して、画像が保存されているフォルダーを参照します。その後、プログラムはフォルダ(すべてのサブフォルダ)の画像(.jpg、.png、.bmp、.gif)のスキャンを開始します。多くの写真をスキャンしたい場合、プログラムが画像ファイルを完全にロードして解析する必要があるため、これには時間がかかります。

スキャン中は、ステータスバーに進捗率が表示されます。完璧ではないことがわかった画像は、リストに直接表示されます。リストの画像をクリックすると、画像のプレビューが表示されます。多くの場合、画像にはファイル形式にわずかな問題があるだけで、画像は正常に表示されます。それ以外の場合、画像はまったくレンダリングされず、プレビューは黒になります。画像が破損する場合があり、上のスクリーンショットのようなものが表示されます。

非常に便利なトリックは、列ヘッダーをクリックしてReason、画像がどれだけひどく破損しているかによってソートされることです(たとえば、まだ正しくレンダリングされるすべての不良ファイル形式が下に移動して、より深刻なケースに集中できます) 。

また、最初のスキャンが完了し、別のスキャンを開始した場合、結果は単純にリストに追加されます。そのため、画像を含むさまざまなフォルダがある場合、新しいスキャンを開始するときにリストをクリアせずに、それらを順番にスキャンするだけです。リストをクリアする場合は、コンテキストメニューを使用してをクリックしますClear list

リンク
Windows、Linux、およびOS Xのダウンロードは、https
//www.coderslagoon.comにあります。

ソースコードはこちら:https :
//github.com/llaith/BadPeggy


修正してくれてありがとう。少し使用方法の情報を追加しました(プログラムは非常に自明ですが)。
ポール

ソースコードのリンクが壊れています。
ニコラスラウル

9

JPEGファイルのjpeginfo ' -c'オプションを試してください。

不良メモリカードでも破損が発生するのを見てきました。
あなたが望むものは可能かつ利用可能であるべきです、グラフィックファイルの破損をチェックしてください。
オンラインのグラフィックファイル形式百科事典のセクション。

また、参照ファイルの整合性チェックにA基本的な入門PNGでいます

このStackoverflowの質問に興味があるかもしれ
ません。画像(PNG、JPEG、またはGIF)が破損しているどうかをプログラムで確認するにどうすればよいですか?


更新ソースのtarballのためのバージョン1.6.1によってティモKokkonen
マシン用のバイナリをビルドできるはずです。


残念ながら、Windowsポートは見つかりません。
Synetech

jpeginfoはオープンソースです。tarballを取得してシステムでコンパイルできるはずです(おそらく、libjpegのあるCygwinで)。
ニック

少なくともGIFとPNGもスキャンする必要があるので、どちらにしても意味がありません。
Synetech

1
@nik-jpeginfoのtarballの一部であるauxディレクトリは、Windowsではその名前で作成できないため、Windowsで展開することさえ難しく、単独でビルドすることはできません。Windowsでビルドできましたか?
ルーク

jpeginfo -c *.JPG | ag (WARNING|ERROR)私のために働いた
セルロン

3

ImageMagickの識別プログラムは、画像が破損しているかどうかを知らせます。識別からの0以外のリターンコードの「for i in find」ループテストでは、テストを簡単にスクリプト化して、破損または破損したファイルのリストをダンプできます。PowerShellを使用したWindowsでも機能します。

ここに画像の説明を入力してください

パスに変更を加えた次のコードは、PowerShellでうまく機能します

$stream = [System.IO.StreamWriter] "corrupt_jpegs.txt" 
get-childitem "c:\" -include *.jpg -recurse | foreach ($_) { 
    & "C:\Program Files\ImageMagick-6.7.1-Q16\identify.exe" $_.fullname > $null 
    if($LastExitCode -ne 0){ 
        $stream.writeline($_.fullname) 
    } 
} 
$stream.close()

私はしばらくImageMagickを使用していませんが(前回試したときにバグがありました)、調査します。提案をありがとう。
Synetech

1
ビューアーツールにはまだバグがありますが、同様の問題で私にとっては問題なく動作します。このようなPowerShellスクリプトを使用して、破損した画像ファイルまたは長さ0の画像ファイルのリストを取得しました。
オールドウルフ

@Synetech inc。申し訳ありませんが、画像が投稿されているため、フォーマットされたコードで元の投稿を更新することはできません。これをうまくフォーマットすることもできません。サンプルPowerShellスクリプト:(パス、ファイルタイプなどを調整します。)$ stream = [System.IO.StreamWriter] "corrupt_jpegs.txt" get-childitem "c:\" -include * .jpg -recurse | foreach($ _){& "C:\ Program Files \ ImageMagick-6.7.1-Q16 \ identify.exe" $ _。fullname> $ null if($ LastExitCode -ne 0){$ stream.writeline($ _。 fullname)}} $ stream.close()
OldWolf

1
コマンドラインから、identify破損したJPEGデータを表示できますが-verbose、通常は表示されません。
ケノーブ

3

これは、Python Imaging Libraryの.verify()コマンドを使用して実行できます。[1]

これをWindowsで実行するには、Python(現在の最新リリースのPython 2をインストールしました)をインストールしてから、Pillow(Python Imaging Library(PIL)のフォーク)をインストールします。次に、jpeg_corrupt.py [2]のコードをコピーし、その内容を.PYファイル(例:jpeg_corrupt.py)に保存します。

jpeg_corrupt.pyの次のコード行
self.globs = ['*.jpg', '*.jpe', '*.jpeg']

self.globs = ['*.jpg', '*.jpe', '*.jpeg', '*.png', '*.gif']
これに変更したことに注意してください。これにより、.PNGおよび.GIFファイルもスキャンされます。

その後、Windowsコマンドプロンプト(cmd.exe)から次のように実行できます。 C:\Python27\python.exe "C:\Directory containing the .PY file\jpeg_corrupt.py" "C:\Directory of folder to be scanned"

コマンドの最初の部分「C:\ Python27 \ python.exe」は、インストールしたPythonのバージョンとインストール先のディレクトリによって異なる場合があります。私の例では、Python 2.7のデフォルトのインストールディレクトリです。

指定したディレクトリとそのすべてのサブディレクトリにあるすべてのJPG、GIF、PNG画像をスキャンする必要があります。破損したイメージファイルを検出すると、出力が表示されます。

OPのサンプル画像でこれを実行すると、次のエラーメッセージが表示されました:...\YcB9n.png: string index out of range

コードは.BATスクリプトファイルにも入力できるため、コマンドプロンプトを使用せずに、指定したディレクトリで簡単に実行できます。

C:\Python27\python.exe "C:\Directory containing the .PY file\jpeg_corrupt.py" "%CD%"
pause



ソース:

[1]:スタックオーバーフローの回答-「画像(PNG、JPEG、またはGIF)が破損しているかどうかをプログラムで確認するにはどうすればよいですか?」ChristopheD
[2]:[1]にリンクされたSO回答のDenilsonSáによるコメント


4
jpgファイルの一部をランダムに削除しました-スクリプトには何も表示されませんでした。それだけで、ほとんどの最悪のケースでエラーを検出-ヘッダが完全例えばミスしたとき...
パベルVlasov

まさに、jpeginfoについても同じことが言えます。
wp78de

2

galacticninjaの回答のコードを修正して、OPが望んでいたことを正確に行いました。同じ方法で実行されますがC:\、コマンドプロンプトに画像を一覧表示するだけでなく、ファイルをルートディレクトリのcatchフォルダーに移動します。

変更したコードはPastebin以下で見つけることができます:

#This program will scan a directory and all it's subdirectories for corrupted jpg, png, gif, and bmp images and collect them in a Catch folder

#To run this program you will need to install Python 2.7 and PILLOW
#Once installed save this file in a notepad document with the .py extension
#Than run cmd.exe and type the following: C:\Python27\python.exe "C:\Directory this is saved in\this.py" "C:\Directory to be scanned"
#You must make a folder called Catch in your root C:\ directory for the corrupted images to be collected in


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# vi:ts=4 sw=4 et

# Okay, this code is a bit ugly, with a few "anti-patterns" and "code smell".
# But it works and I don't want to refactor it *right now*.

# TODO:
#  * Refactor it a little
#  * Add support for custom filename filter (instead of the hardcoded one)

#Big thanks to denilsonsa for writing most of this code at https://bitbucket.org/denilsonsa/small_scripts/src/542edd54d290d476603e939027ca654b25487d85/jpeg_corrupt.py?at=default


import getopt
import fnmatch
import re
import os
import os.path
import sys
import PIL.Image


available_parameters = [
    ("h", "help", "Print help"),
    ("v", "verbose", "Also print clean files"),
]


class ProgramOptions(object):
    """Holds the program options, after they are parsed by parse_options()"""

    def __init__(self):
        self.globs = ['*.jpg', '*.jpe', '*.jpeg', '*.gif', '*.png', '*.bmp']
        self.glob_re = re.compile('|'.join(
            fnmatch.translate(g) for g in self.globs
        ), re.IGNORECASE)

        self.verbose = False
        self.args = []


def print_help():
    global opt
    scriptname = os.path.basename(sys.argv[0])
    print "Usage: {0} [options] files_or_directories".format(scriptname)
    print "Recursively checks for corrupt image files"
    print ""
    print "Options:"
    long_length = 2 + max(len(long) for x,long,y in available_parameters)
    for short, long, desc in available_parameters:
        if short and long:
            comma = ", "
        else:
            comma = "  "

        if short == "":
            short = "  "
        else:
            short = "-" + short[0]

        if long:
            long = "--" + long

        print "  {0}{1}{2:{3}}  {4}".format(short,comma,long,long_length, desc)

    print ""
    print "Currently (it is hardcoded), it only checks for these files:"
    print "  " + " ".join(opt.globs)


def parse_options(argv, opt):
    """argv should be sys.argv[1:]
    opt should be an instance of ProgramOptions()"""

    try:
        opts, args = getopt.getopt(
            argv,
            "".join(short for short,x,y in available_parameters),
            [long for x,long,y in available_parameters]
        )
    except getopt.GetoptError as e:
        print str(e)
        print "Use --help for usage instructions."
        sys.exit(2)

    for o,v in opts:
        if o in ("-h", "--help"):
            print_help()
            sys.exit(0)
        elif o in ("-v", "--verbose"):
            opt.verbose = True
        else:
            print "Invalid parameter: {0}".format(o)
            print "Use --help for usage instructions."
            sys.exit(2)

    opt.args = args
    if len(args) == 0:
        print "Missing filename"
        print "Use --help for usage instructions."
        sys.exit(2)


def is_corrupt(imagefile):
    """Returns None if the file is okay, returns an error string if the file is corrupt."""
    #http://stackoverflow.com/questions/1401527/how-do-i-programmatically-check-whether-an-image-png-jpeg-or-gif-is-corrupted/1401565#1401565
    try:
        im = PIL.Image.open(imagefile)
        im.verify()
    except Exception as e:
        return str(e)
    return None


def check_files(files):
    """Receives a list of files and check each one."""
    global opt
    i = 0
    for f in files:
        # Filtering JPEG, GIF, PNG, and BMP images
        i=i+1
        if opt.glob_re.match(f):
            status = is_corrupt(f)
            if opt.verbose and status is None:
                status = "Ok"
            if status:
                file = "{0}".format(f, status)
                print file
                shorthand = file.rsplit('\\', 1)
                extention =shorthand[1]
                fullFileName = "C:\Catch" + "\\" + extention
                os.rename(file, fullFileName)


def main():
    global opt
    opt = ProgramOptions()
    parse_options(sys.argv[1:], opt)

    for pathname in opt.args:
        if os.path.isfile(pathname):
            check_files([pathname])
        elif os.path.isdir(pathname):
            for dirpath, dirnames, filenames in os.walk(pathname):
                check_files(os.path.join(dirpath, f) for f in filenames)
        else:
            print "ERROR: '{0}' is neither a file or a dir.".format(pathname)


if __name__ == "__main__":
    main()

2

imagemagickをインストールします。Macを使用している場合はHomebrewを使用できます。

brew update && brew install imagemagick

その後、この小さなPythonスクリプトを使用できます。

import os
from subprocess import Popen, PIPE

def checkImage(fn):
    proc = Popen(['identify', '-verbose', fn], stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    exitcode = proc.returncode

    return exitcode, out, err

for directory, subdirectories, files in os.walk('/Your/Path/To/Files/'):
    for file in files:
        filePath = os.path.join(directory, file)
        code, output, error = checkImage(filePath)
        if code != 0 or error != '':
            print(str(code)+' '+error)
            #os.remove(filePath)

/Your/Path/To/Files/破損したイメージを削除する場合は、最後の行を置き換えてコメント解除します。


1

identifyImageMagickパッケージから使用します。

サンプル例:

identify -verbose -regard-warnings my_file.jpg >/dev/null && echo File is OK. || echo File is corrupted.

また、次のコマンドは、現在のフォルダー内のすべての破損したJPEGファイルを識別します。

find . -name \*.jpg -exec identify -verbose -regard-warnings {} >/dev/null "+"

0

Perlがインストールされている場合、このスクリプトを使用できます。スクリプトを実行する前に、f.txtでチェックインするファイルのリストを保存する必要があります。Irfanviewを使用してこのリストを作成できます。(サブフォルダーからすべてのサムをロードして、txtに保存します)。正常なファイルのリストはokf.txtに保存され、破損したファイルはbrokenf.txtにリストされます。

======================

use Image::Magick;

open(BROKEN, ">>brokenf.txt");  # Open for appending
open(OK, ">>okf.txt");  # Open for appending
$list='f.txt';          
open(TOSORT, $list) or die("Could not open  file."); 
foreach $pic (<TOSORT>)  {     
    chomp($pic);   
    $p = new Image::Magick;
    $s = 0;    
    $error = $p->Read($pic);
        if ($error) {print BROKEN $pic . "\n";
                   }     
           else {
                  print OK $pic . "\n"; 
                }  
    }
close(TOSORT);
close(BROKEN);
close(OK);
    }

close(TOSORT);
close(BROKEN);
close(OK);

0

私のオープンソースPyhtonスクリプトcheck-media-integrityは、写真とビデオ/オーディオファイルの整合性をチェックします。Pillowモジュール、ImageMagickおよびFFmpegラッパーを使用して、ファイルのデコードを試みます。

Pillow image.verifyでは、すべての欠陥が表示されません(たとえば、切り捨ては無視されます)。そのため、画像/デコード+操作も実行しました。


0

このブログ投稿には、破損したイメージファイルを(検出および)修復できる5つのツールがリストされています。その中で唯一無料のものはファイル修復2.1です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.