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


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 з відкритим кодом; ви маєте змогу дістати тарбол та компілювати його у своїй системі (можливо, із Cygwin, у якого є libjpeg).
nik

Це так чи інакше, тому що мені також потрібно сканувати принаймні GIF та PNG.
Synetech

1
Каталог @nik - aux, який є частиною тарболу jpeginfo, не може бути створений під цим іменем у Windows, тому це дуже важко навіть витягувати під Windows, а менше будувати його. Вам вдалося побудувати його під Windows?
Грак

jpeginfo -c *.JPG | ag (WARNING|ERROR)працював на мене
Selrond

3

Програма виявлення ImageMagick повідомить вас про те, що зображення пошкоджене. Тестування циклу "для i in find" циклу повернення коду, який не відповідає 0, дозволить вам досить легко скриптувати тест, щоб скинути список пошкоджених або пошкоджених файлів. Він працює і в Windows з PowerShell.

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

Наведений нижче код із змінами для вашого шляху добре працює в powerhell

$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
Інструмент перегляду все ще баггі, але ідентифікація чудово працювала для мене із подібною проблемою. Я використовував такий скрипт powerhell, щоб отримати список пошкоджених файлів зображень або 0 довжини.
OldWolf

@Synetech вкл. На жаль, не вдається оновити оригінальну публікацію за допомогою форматованого коду, оскільки зображення було розміщено на ній, і я не можу зробити так, щоб воно також було добре відформатоване. Зразок сценарію Powershell: (коригуйте свої шляхи, типи файлів тощо.) $ Stream = [System.IO.StreamWriter] "corrupt_jpegs.txt" get-childitem "c: \" -include * .jpg -recurse | foreach ($ _) {& "C: \ Program Files \ ImageMagick-6.7.1-Q16 \ identi.exe" $ _. fullname> $ 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 (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]


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

Точно те саме стосується jpeginfo.
wp78de

2

Я змінив код з відповіді галактиніни, щоб зробити саме те, що хотів ОП. Він запускається так само, проте він перемістить файли в папку 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, а пошкоджені файли - у розбитих файлах.

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

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 перевіряє цілісність зображень та відео / аудіофайлів. Для спроби декодування файлів використовуються модулі Подушки, обгортки ImageMagick і FFmpeg.

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


0

У цьому дописі блогу перелічено п'ять інструментів, за допомогою яких можна (виявити та) відновити пошкоджені файли зображень. Єдиний безкоштовний серед них - Ремонт файлів 2.1.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.