web-dev-qa-db-ja.com

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

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


説明:

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

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

さらに、一部の画像形式ではサムネイルの小さいバージョンの画像が埋め込まれているため、実際のファイル(つまり、フルサイズで表示した場合の画像)が破損している可能性があるため、サムネイルをスキャンしても破損していない可能性があります。


次に例をいくつか示します。

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

damaged image

(3つ目はアップロードさえしません正しいヘッダーもないためです!)

28
Synetech

私が同じ質問に答えようとしているときにこれを偶然見つけたので、私が見つけた別の素晴らしい解決策を追加します:

Bad Peggy

Screenshot of the application

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

スキャン中は、ステータスバーに進行状況のパーセンテージが表示されます。完璧でないと判明した画像は、リストに直接表示されます。リスト上の画像をクリックすると、画像のプレビューが表示されます。多くの場合、画像のファイル形式には小さな問題があり、画像は問題なく表示されます。それ以外の場合、画像はまったくレンダリングされず、プレビューは真っ黒になります。画像が破損して、上のスクリーンショットのようなものが表示される場合があります。

非常に便利なトリックは、Reasonの列ヘッダーをクリックすると、画像が損傷の程度に応じて並べ替えられます(たとえば、まだ正しくレンダリングされているすべての不良ファイル形式が下に移動し、焦点を合わせることができます)より深刻な場合)。

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

リンク
Windows、Linux、OS X用のダウンロードは、次の場所にあります。
https://www.coderslagoon.com

ソースコードはここにあります:
https://github.com/llaith/BadPeggy

14
Paul

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

あなたが示す破損は、不良のメモリカードでも発生することを確認しました。
あなたが望むものは可能で利用可能でなければなりません、チェックしてください グラフィックファイルの破損 ;
オンラインのセクション Encyclopedia of Graphics File Formats

[〜#〜] png [〜#〜]機能の基本的な紹介のFile Integrity Checksも参照してください。

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


UpdateSource tarball for version 1.6.1 by Timo Kokkonen
マシンのバイナリを構築できるはずです。

10
nik

これは、 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)が破損しているかどうかをプログラムで確認するにはどうすればよいですか?」クリストフD
[2]:SO [1]でリンクされた回答におけるDenilsonSáによるコメント

4
galacticninja

ImageMagickの識別 プログラムは、イメージが破損しているかどうかを通知します。 Identifyからの0以外の戻りコードに対する「for i in find」ループテストを使用すると、テストのスクリプトを簡単に作成して、破損または破損したファイルのリストをダンプできます。 PowerShellを使用してWindowsでも動作します。

enter image description here

パスを変更した次のコードは、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()
4
OldWolf

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/破損した画像を削除する場合は、最後の行のコメントを外してください。

3
Gotenks

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

あなたは私の変更されたコードを見つけることができます 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()
3
CosmicNaut

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

枕image.verifyはすべての欠陥を認識しません(たとえば、切り捨てを無視します)。このため、画像/デコード+操作も実行しました。

2
Fabiano Tarlao

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

1
root

ImageMagickパッケージのidentifyを使用します。

サンプルの例:

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 "+"
1
kenorb

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
ijin