26

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


Объяснение:

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

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

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


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

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

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

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

10 ответов10

8

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

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

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

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


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

8

Поскольку я наткнулся на это, пытаясь ответить на тот же вопрос, я добавлю еще одно замечательное решение, которое я нашел:

Бад Пегги

Снимок экрана приложения

использование
В меню выберите « File > Scan а затем с помощью диалогового окна «Файл» найдите папку, в которой находятся изображения. Затем программа начнет сканирование папки и всех вложенных папок на наличие изображений (.jpg, .png, .bmp, .gif). Если вы хотите отсканировать много изображений, это займет некоторое время, потому что программе необходимо полностью загрузить и проанализировать файл изображения, поэтому вы можете захотеть запустить его в одночасье.

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

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

Также, если первое сканирование завершено, и вы начинаете другое сканирование, результаты будут просто добавлены в список. Таким образом, если у вас много разных папок с изображениями, вы можете просто сканировать их последовательно без очистки списка при запуске нового сканирования. Если вы хотите очистить список, используйте контекстное меню и нажмите « Clear list .

связи
Загрузки для Windows, Linux и OS X можно найти здесь:
https://www.coderslagoon.com

Исходный код здесь:
https://github.com/coderslagoon/badpeggy

3

Это можно сделать с помощью команды .verify() библиотеки изображений Python. [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)?"Кристоф
[2]: Комментарий Денилсона Са в ответе SO, связанном с [1]

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 сообщит вам, повреждено ли изображение. Циклическое тестирование «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()
1

Установите 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

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

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 не видит все дефекты (например, игнорирует усечение), по этой причине я также выполнил манипуляции с изображением / декодированием +.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .