Automatisieren des Scannens von Grafikdateien auf Beschädigungen

27

Kennt jemand eine Möglichkeit, Grafikdateien (insbesondere JPEG, GIF und PNG) (vorzugsweise automatisiert) auf Beschädigung zu überprüfen?


Erläuterung:

Vor einigen Tagen funktionierte ein Befehl nicht ordnungsgemäß und löschte schließlich Tausende von Grafikdateien von einem FAT32-Volume, auf dem praktisch nicht genügend Speicherplatz vorhanden war. Ich habe mehrere verschiedene Datei- / Foto-Wiederherstellungsprogramme verwendet, aber natürlich sind sie in ihrer Wiederherstellungsrate begrenzt (obwohl das Volume zum Glück 8-KB-Cluster hat, was ein wenig hilft).

Auf jeden Fall sind einige der größeren Dateien, die fragmentiert wurden, jetzt beschädigt. Einige von ihnen sind überhaupt keine echten Dateien (die Wiederherstellungssoftware hat lediglich die Cluster gesichert, auf die durch jetzt überschriebene Verzeichniseinträge verwiesen wurde), während andere aufgrund von Fragmentierung beschädigt sind.

Da in einigen Bildformaten eine kleinere Version des Bildes als Miniaturbild eingebettet ist, ist das Durchsuchen der Miniaturbilder auf Beschädigung nicht zuverlässig, da sie möglicherweise intakt sind, während die eigentliche Datei (dh das Bild in voller Größe) beschädigt sein kann.


Hier einige Beispiele:

Hier ist der zweite. Es ist so beschädigt, dass es nichts anzeigt.

beschädigtes Bild

(Ein dritter würde nicht einmal hochladen, weil er nicht einmal den richtigen Header hat!)

Synetech
quelle
Du meinst visuelle Korruption, nehme ich an? Ich würde das LIEBEN ... endlich konnte ich aufhören, die Thumbnails meiner Comics nach kaputten JPGs zu durchsuchen.
Shinrai
Optisch oder strukturell. Ich habe eine App gefunden, die das angeblich getan hat, aber viele Dateien übersehen hat, die nicht einmal den Header hatten !
Synetech
Oh, das Zeug ist mir gar nicht eingefallen. Ja, bitte ... das muss irgendwo existieren, oder?
Shinrai
1
Können Sie ein oder mehrere Beispiele einer solchen kaputten Datei hochladen und in Ihrer Frage darauf verlinken?
Slhck
@Shinrai, das Untersuchen der Miniaturbilder ist nicht zuverlässig, da viele Bildformate eine separate Miniaturbildversion enthalten, die in das Bild eingebettet ist und möglicherweise intakt ist. Deshalb ist manchmal ein Bild, dessen Miniaturbild gut aussieht, beim Öffnen beschädigt.
Synetech

Antworten:

12

Da ich darauf gestoßen bin, während ich versucht habe, die gleiche Frage zu beantworten, füge ich eine weitere großartige Lösung hinzu, die ich gefunden habe:

Schlechte Peggy

Screenshot der Anwendung

Verwendung Wählen
Sie im Menü die Option File > Scanund navigieren Sie im Dateidialog zu dem Ordner, in dem sich die Bilder befinden. Das Programm scannt dann den Ordner und alle Unterordner nach Bildern (.jpg, .png, .bmp, .gif). Wenn Sie viele Bilder scannen möchten, dauert dies einige Zeit, da das Programm die Bilddatei vollständig laden und analysieren muss, sodass Sie sie möglicherweise über Nacht laufen lassen möchten.

Während des Scannens wird ein Prozentsatz des Fortschritts in der Statusleiste angezeigt. Alle Bilder, die nicht perfekt sind, werden direkt in der Liste angezeigt. Wenn Sie auf ein Bild in der Liste klicken, wird eine Vorschau des Bildes angezeigt. Sehr oft hat ein Bild nur ein kleines Problem mit dem Dateiformat, und das Bild sieht trotzdem gut aus. In anderen Fällen wird das Bild überhaupt nicht gerendert und die Vorschau ist nur schwarz. Manchmal ist das Bild beschädigt und Sie sehen so etwas wie auf dem Screenshot oben.

Ein sehr praktischer Trick ist das Anklicken der Spaltenüberschrift. ReasonDie Bilder werden danach sortiert, wie stark sie beschädigt sind. .

Auch wenn der erste Scan abgeschlossen ist und Sie einen weiteren Scan starten, werden die Ergebnisse einfach zur Liste hinzugefügt. Wenn Sie also viele verschiedene Ordner mit Bildern haben, können Sie diese einfach nacheinander scannen, ohne dass die Liste gelöscht wird, wenn Sie einen neuen Scan starten. Wenn Sie möchten, dass die Liste gelöscht wird, verwenden Sie das Kontextmenü und klicken Sie auf Clear list.

Links
Downloads für Windows, Linux und OS X finden Sie hier:
https://www.coderslagoon.com

Der Quellcode ist hier:
https://github.com/llaith/BadPeggy

Paul
quelle
Danke für das Update. Ich habe ein paar Nutzungsinformationen hinzugefügt (obwohl das Programm sehr selbsterklärend ist).
Paul
Der Quellcode-Link ist fehlerhaft.
Nicolas Raoul
9

Probieren Sie die Option jpeginfo ' -c' für Ihre JPEG-Dateien aus.

Ich habe gesehen, dass die Korruption, die Sie zeigen, auch bei fehlerhaften Speicherkarten auftritt.
Was Sie wollen, sollte möglich und verfügbar sein, überprüfen Sie die Korruption der Grafikdateien ;
Ein Abschnitt aus der Online- Enzyklopädie der Grafikdateiformate .

Siehe auch Dateiintegritätsprüfungen in einer grundlegenden Einführung in PNG- Funktionen .

Diese Frage zum Stapelüberlauf könnte Sie interessieren:
Wie überprüfe ich programmgesteuert, ob ein Bild (PNG, JPEG oder GIF) beschädigt ist ?


Update : Quell-Tarball für Version 1.6.1 von Timo Kokkonen .
Sie sollten in der Lage sein, eine Binärdatei für Ihren Computer zu erstellen.

nik
quelle
Leider kann ich keine Windows-Ports finden.
Synetech
jpeginfo ist Open Source; Sie sollten in der Lage sein, den Tarball auf Ihrem System zu kompilieren (möglicherweise mit Cygwin, das libjpeg hat).
Nik
Es geht in beiden Fällen nicht, da ich mindestens GIFs und PNGs scannen muss.
Synetech
1
@nik - Aux-Verzeichnis, das Teil von jpeginfos Tarball ist, kann unter diesem Namen unter Windows nicht erstellt werden, was es sehr schwierig macht, es selbst unter Windows zu extrahieren, und es weniger alleine zu erstellen. Haben Sie es geschafft, es unter Windows zu erstellen?
Rook
jpeginfo -c *.JPG | ag (WARNING|ERROR)arbeitete für mich
Selrond
3

Das Identifizierungsprogramm von ImageMagick zeigt an , ob ein Bild beschädigt ist. Mit einer 'for i in find'-Schleife, die auf einen Rückgabewert ohne 0 von' identity 'testet, können Sie den Test ziemlich einfach mit einem Skript ausführen, um eine Liste beschädigter oder beschädigter Dateien zu sichern. Es funktioniert auch unter Windows mit PowerShell.

Bildbeschreibung hier eingeben

Der folgende Code mit Änderungen für Ihren Pfad funktioniert gut in 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
quelle
Ich habe ImageMagick eine Weile nicht mehr verwendet (es hatte Fehler, als ich es das letzte Mal versuchte), aber ich werde es untersuchen. Danke für den Vorschlag.
Synetech
1
Das Viewer-Tool ist immer noch fehlerhaft, aber die Identifizierung hat bei mir mit einem ähnlichen Problem hervorragend funktioniert. Ich habe ein Powershell-Skript wie dieses verwendet, um eine Liste mit beschädigten oder 0-fachen Bilddateien zu erhalten.
OldWolf
@Synetech inc. Entschuldigung, der ursprüngliche Beitrag kann nicht mit formatiertem Code aktualisiert werden, da ein Bild darauf gepostet wurde, und ich scheine auch nicht in der Lage zu sein, das Bild gut zu formatieren. Beispiel für ein Powershell-Skript: (Passen Sie die Pfade, Dateitypen usw. an.) $ Stream = [System.IO.StreamWriter] "corrupt_jpegs.txt" get-childitem "c: \" -include * .jpg -recurse | foreach ($ _) {& "C: \ Programme \ ImageMagick-6.7.1-Q16 \ identity.exe" $ _. vollständiger Name> $ null if ($ LastExitCode -ne 0) {$ stream.writeline ($ _. fullname)}} $ stream.close ()
OldWolf
1
Über die Befehlszeile identifykönnen beschädigte JPEG-Daten mit angezeigt werden -verbose, normalerweise wird dies nicht angezeigt.
Kenorb
3

Dies kann mit dem Befehl der Python Imaging-Bibliothek erfolgen.verify() . [1]

Um dies unter Windows auszuführen, installieren Sie Python (ich habe die aktuellste Version von Python 2 installiert) und anschließend Pillow (eine Abzweigung der Python Imaging Library (PIL)). Kopieren Sie dann den Code von jpeg_corrupt.py [2] und speichern Sie den Inhalt in einer .PY-Datei, z. B. jpeg_corrupt.py.

Beachten Sie, dass ich die folgende Codezeile in jpeg_corrupt.py geändert habe :
self.globs = ['*.jpg', '*.jpe', '*.jpeg']
in
self.globs = ['*.jpg', '*.jpe', '*.jpeg', '*.png', '*.gif']
Dies, damit auch PNG- und GIF-Dateien gescannt werden.

Es kann dann über die Windows-Eingabeaufforderung (cmd.exe) wie folgt ausgeführt werden: C:\Python27\python.exe "C:\Directory containing the .PY file\jpeg_corrupt.py" "C:\Directory of folder to be scanned"

Der erste Teil des Befehls " C: \ Python27 \ python.exe " kann je nach der installierten Version von Python und dem Verzeichnis, in dem Sie es installiert haben, unterschiedlich sein. In meinem Beispiel ist dies das Standardinstallationsverzeichnis von Python 2.7.

Es sollte alle JPG-, GIF- und PNG-Bilder im angegebenen Verzeichnis und in allen seinen Unterverzeichnissen scannen. Es wird eine Ausgabe angezeigt, wenn eine beschädigte Bilddatei erkannt wird.

Ich lief dies auf OP der Probe Bild und es gab diese Fehlermeldung: ...\YcB9n.png: string index out of range.

Der Code könnte auch in eine .BAT-Skriptdatei eingegeben werden, sodass Sie ihn problemlos in einem angegebenen Verzeichnis ausführen können, ohne die Eingabeaufforderung verwenden zu müssen:

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



Quellen:

[1]: Antwort im Stapelüberlauf - "Wie überprüfe ich programmgesteuert, ob ein Bild (PNG, JPEG oder GIF) beschädigt ist?" von ChristopheD
[2]: Kommentar von Denilson Sá in der SO-Antwort in [1]

galacticninja
quelle
4
Ich habe einige Teile einer JPG-Datei nach dem Zufallsprinzip gelöscht - das Skript zeigte nichts an. Es erkennt Fehler in den schlimmsten Fällen nur - wenn der Header zum Beispiel komplett verfehlt wird ...
Pavel Vlasov
Genau das gleiche gilt für jpeginfo.
wp78de
2

Ich habe den Code von galacticninjas Antwort geändert , um genau das zu tun, was OP wollte. Es wird auf die gleiche Weise ausgeführt, jedoch werden die Dateien in einen Catch-Ordner im Stammverzeichnis verschoben, C:\anstatt nur die Bilder an der Eingabeaufforderung aufzulisten.

Sie finden meinen geänderten Code in Pastebin oder unten:

#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()
CosmicNaut
quelle
2

Installieren Sie imagemagick. Wenn Sie auf einem Mac arbeiten, können Sie Homebrew verwenden.

brew update && brew install imagemagick

Dann können Sie dieses kleine Python-Skript verwenden.

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)

Ersetzen Sie /Your/Path/To/Files/die letzte Zeile und entfernen Sie das Kommentarzeichen, wenn Sie die beschädigten Bilder löschen möchten.

Gotenks
quelle
1

Verwendung identifyaus dem ImageMagick-Paket.

Beispielbeispiel:

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

Mit dem folgenden Befehl werden alle beschädigten JPEG-Dateien im aktuellen Ordner identifiziert:

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

Wenn Sie Perl installiert haben, können Sie dieses Skript verwenden. Sie müssen die Liste der Dateien speichern, um f.txt einzuchecken, bevor Sie das Skript ausführen. Sie können diese Liste mit Irfanview erstellen. (lade alle Thumbnails aus den Unterordnern und speichere sie in txt). Die Liste der fehlerfreien Dateien wird in okf.txt gespeichert und beschädigte Dateien in 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);
ijin
quelle
0

Meine Open-Source-Pyhton-Skriptprüfung überprüft die Integrität von Bildern und Video- / Audiodateien. Es verwendet Pillow-Module, ImageMagick- und FFmpeg-Wrapper, um die Dateien zu dekodieren.

Pillow image.verify sieht nicht alle Fehler (ignoriert zB das Abschneiden). Aus diesem Grund habe ich auch Image / Decode + Manipulation durchgeführt.

Fabiano Tarlao
quelle
0

In diesem Blog-Beitrag werden fünf Tools aufgeführt, mit denen beschädigte Bilddateien erkannt und repariert werden können. Die einzige kostenlose davon ist File Repair 2.1.

Wurzel
quelle