Автоматизация сканирования графических файлов на наличие повреждений


28

Кто-нибудь знает способ проверки графических файлов (в частности, JPEG, GIF и PNG) на наличие повреждений (желательно автоматическим способом)?


Объяснение:

Несколько дней назад команда работала некорректно и закончила тем, что удалила тысячи графических файлов с тома FAT32, на котором практически не осталось места. Я использовал несколько разных программ для восстановления файлов / фотографий, но, естественно, они ограничены в том, сколько они могут восстановить (хотя, к счастью, том имеет кластеры 8 КБ, что несколько помогает).

Во всяком случае, некоторые большие файлы, которые были фрагментированы, теперь повреждены. Некоторые из них вообще не являются настоящими файлами (программное обеспечение для восстановления просто сбрасывает кластеры, на которые указывают перезаписанные записи каталога), в то время как другие ломаются из-за фрагментации.

Более того, поскольку некоторые форматы изображений включают уменьшенную версию изображения в виде миниатюры, сканирование миниатюр на предмет повреждения не является надежным, поскольку оно может быть целым, в то время как фактический файл (т. Е. Изображение при просмотре в полном размере) может быть поврежден.


Вот пара примеров:

Вот второй. Он настолько поврежден, что ничего не отображает.

поврежденное изображение

(Третий даже не загружается, потому что у него нет правильного заголовка!)


Я имею в виду визуальную коррупцию? Я бы полюбил это ... наконец, я мог бы перестать смотреть на миниатюры моих комиксов для сломанных jpgs.
Shinrai

Визуальный или структурный. Я нашел одно приложение, которое предположительно сделало это, но оно пропустило много файлов, которые даже не имели заголовка !
Synetech,

О, эта штука даже не пришла мне в голову. Да, пожалуйста ... это должно существовать где-то верно?
Shinrai

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

Попробуйте jpeginfo ' -c' для ваших файлов JPEG.

Я видел, что коррупция, которую вы показываете, случается и с плохими картами памяти.
То, что вы хотите, должно быть возможным и доступным, проверьте « Повреждение графических файлов» ;
раздел из онлайн- энциклопедии графических форматов файлов .

Также см. Проверка целостности файлов в Основном введении в функции PNG .

Возможно, вас заинтересует вопрос Stackoverflow:
как программно проверить, не повреждено ли изображение (PNG, JPEG или GIF) ?


Обновление : Источник тарбол для версии 1.6.1 от Timo Кокконны .
Вы должны быть в состоянии построить двоичный файл для вашей машины.


К сожалению, я не могу найти порты Windows.
Synetech

jpeginfo является открытым исходным кодом; у вас должна быть возможность получить tarball и скомпилировать его в вашей системе (возможно, с Cygwin, у которого есть libjpeg).
Ник

Это спорный вопрос так или иначе, потому что мне нужно проверять по крайней мере , GIFs и PNG файлов , а также.
Synetech

1
@nik - каталог aux, который является частью архива jpeginfo, не может быть создан под этим именем в Windows, что делает его очень трудным даже для извлечения в Windows, а не только для его сборки. Вам удалось собрать его под Windows?
Ладья

jpeginfo -c *.JPG | ag (WARNING|ERROR)работал для меня
Селронд

3

Программа идентификации ImageMagick сообщит вам, повреждено ли изображение. Циклическое тестирование «for i in find» для кода возврата none-0 из идентификатора позволит вам довольно легко выполнить сценарий теста, чтобы вывести список поврежденных или поврежденных файлов. Он работает на Windows с PowerShell тоже.

введите описание изображения здесь

Следующий код с изменениями для вашего пути хорошо работает в 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, как этот, чтобы получить список поврежденных и / или файлов изображений нулевой длины.
OldWolf

@Synetech inc. Извините, я не могу обновить исходное сообщение с отформатированным кодом, так как к нему было добавлено изображение, и я, похоже, тоже не могу его правильно отформатировать. Пример сценария Powershell: (настройте пути, типы файлов и т. Д.) $ Stream = [System.IO.StreamWriter] "dirty_jpegs.txt" get-childitem "c: \" -include * .jpg -recurse | foreach ($ _) {& "C: \ Program Files \ ImageMagick-6.7.1-Q16 \ identif.exe" $ _. полное имя> $ null if ($ LastExitCode -ne 0) {$ stream.writeline ($ _. полное имя)}} $ stream.close ()
OldWolf

1
Из командной строки identifyможет отображать поврежденные данные JPEG с помощью -verbose, обычно они не отображаются.
kenorb

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]: Комментарий Денилсона Са в ответе SO, связанном в [1]


4
Я удалил некоторые части файла jpg случайным образом - скрипт ничего не показал. Он обнаруживает ошибки только в самых худших случаях - например, когда полностью пропущен заголовок ...
Павел Власов

Точно так же и для jpeginfo.
wp78de

2

Я изменил код из ответа 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()

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

Используйте identifyиз пакета ImageMagick.

Пример примера:

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-целостности проверяет целостность изображений и видео / аудио файлов. Он использует модули Pillow, обертки ImageMagick и FFmpeg, чтобы попытаться расшифровать файлы.

Подушка image.verify не видит все дефекты (например, игнорирует усечение), поэтому я также выполнил манипуляции с изображением / декодированием +.


0

В этом блоге перечислены пять инструментов, которые могут (обнаруживать и восстанавливать ) поврежденные файлы изображений. Единственным бесплатным среди них является File Repair 2.1.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.