Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программное обеспечение Windows (http://forum.oszone.net/forumdisplay.php?f=7)
-   -   Пакетная проверка кучи jpg/jpeg файлов на предмет повреждений (http://forum.oszone.net/showthread.php?t=209258)

Jr.Janitor 17-06-2011 18:54 1696573

Пакетная проверка кучи jpg/jpeg файлов на предмет повреждений
 
Вложений: 1
На форуме (да и на необъятных просторах сети) поднято множество тем по восстановлению потерянных/поврежденных фотографий, но иногда бывает нужно просто перебрать все графические файлы (наверно 99% - jpg) в каталогах и найти те, что пострадали. Пробовал различные пакетные конверторы (больше всех понравился IrfanView и FastStone), в надежде на получение списка файлов, содержащих ошибки, но все совершенно нормально открывали порченные файлы.

Это расстраивает по 2м причинам:
1. я был уверен, что должно быть великое множество средств диагностики графических файлов
2. может ли быть такое, что явное повреждение данных jpeg-файла не может быть диагностировано?

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

Просил одного знакомого программера сделать эксперимент - открыть средствами GDI заведомо битый JPG и посмотреть, возвращает ли библиотечка хоть какую-то ошибку, тогда можно было-бы написать небольшую програмку по проверки файлов из списка, с формированием списков хороших/поврежденных файлов, но тот уперся, сославшись, что если просмотрщик показывает битый JPG и не ругается, то и какой-нить "TJpegImage" не позволит обнаружить повреждение.

* прикладываю пример умышленно "битого" Jpeg`а, может кто чего попробует и посоветует?

Iska 17-06-2011 20:33 1696627

Jr.Janitor, я тоже в своё время искал что-либо подобное, но ничего внятного не нашёл. Я ограничился таким способом:

1. Устанавливал ImageMagick, конкретно версию для работы с 8-битным цветом отсюда: ImageMagick: Install from Binary Distribution.

2. Использовал такой сценарий vbscript:
читать дальше »
Код:

Option Explicit

On Error Resume Next

Const ERROR_SUCCESS = 0

Dim objArgs
Dim objImg
Dim strResult
Dim sMsgs

Set objArgs = WScript.Arguments

If objArgs.Count <> 1 Then
        WScript.Echo _
                "Usage:  " & WScript.ScriptName & " <FileNamesTemplate>" & vbCrLf & vbCrLf & _
                "Example: " & WScript.ScriptName & " ""c:\windows\*.bmp"""
       
        WScript.Quit 2
Else
        Set objImg = CreateObject("ImageMagickObject.MagickImage.1")
       
        strResult = objImg.Identify("-format", "Name:[%f] Type:[%m] Dim:[%wx%hx%z]\r\n", objArgs(0))
        'strResult = Replace(strResult, vbCrLf, " \n ")
       
        If Err.Number <> ERROR_SUCCESS Then
                ShowError
                Set objImg = Nothing
                WScript.Quit 1
        Else
                'WScript.Echo "NOERROR" & vbCrLf & strResult
                WScript.Echo strResult
                Set objImg = Nothing
                WScript.Quit 0
        End If
End If

'=========================================================================================
Sub ShowError
        sMsgs = ""

        If BasicError(Err.Number) > 5000 Then
                'sMsgs = " ImageMagickObject" & vbCrLf
        End If

        'WScript.Echo sMsgs & vbCrLf & Err.Number & ": " & Err.Description
        WScript.Echo Err.Description
End Sub
'=========================================================================================

'=========================================================================================
Function BasicError(e)
        BasicError = e And &HFFFF&
End Function
'=========================================================================================



3. Привязывал скрипт для выделенного файла в Far Manager посредством «User Menu» и макроса для проверки.

Выглядело в результате сие примерно так:
читать дальше »
Код:

╔═════════════ Ошибок не обнаружено ═════════════╗
║ Name:[PageAll.jpg] Type:[JPEG] Dim:[616x166x8] ║
║                                                ║
╟────────────────────────────────────────────────╢
║                    { OK }                    ║
╚════════════════════════════════════════════════╝


Или так (Ваш файл):
читать дальше »
Код:

╔═══════════════════════════════════ Найдены ошибки ════════════════════════════════════╗
║ identity: 325: Corrupt JPEG data: premature end of data segment `C:\attachment.jpg':  ║
║      identity: 325: Corrupt JPEG data: bad Huffman code `C:\attachment.jpg':        ║
║                                                                                      ║
╟───────────────────────────────────────────────────────────────────────────────────────╢
║                                        { OK }                                        ║
╚═══════════════════════════════════════════════════════════════════════════════════════╝



Подобным же образом у меня сделан скрипт на группу выделенных в Far Manager'е файлов. Приводить его не буду, ибо основная идея показана во втором пункте: попытка идентификации изображения, отлов возможной ошибки при этом, далее выход из скрипта с установлением нулевого/не нулевого кода ошибки, который затем используется во внешнем приложении (в данном случае — Far Manager'е) для отображения соответствующего сообщения, а как и чем будете пользоваться Вы — решать Вам.

К сожалению, в то время утилита «identify.exe» ImageMagick (как сейчас — не знаю) не устанавливала ненулевой код возврата при ошибке в изображении, а так можно было бы вполне обойтись без скрипта VBScript (в моём, понятно, случае), одним пакетным файлом с вызовом «identify.exe».

P.S. Вполне возможно, что я плохо искал, или что ситуация изменилась за прошедшее время, и коллеги посоветуют более простое решение.

Iska 17-06-2011 20:59 1696635

Дополнение:

1. Jr.Janitor, если у Вас есть кто может написать — то можно использовать библиотеки ImageMagick для получения утилиты с потребной именно Вам функциональностью.

2. После поиска обнаружилось, что «identify.exe» всё-таки устанавливает errorlevel при использовании параметра «-regard-warnings»:
Код:

C:\>"C:\Program Files\ImageMagick-6.3.4-Q8\identify.exe" -regard-warnings attachment.jpg 1>nul && echo 1 || echo 2
identify.exe: Corrupt JPEG data: premature end of data segment `attachment.jpg'.
identify.exe: Corrupt JPEG data: bad Huffman code `attachment.jpg'.
2


Busla 18-06-2011 20:15 1697171

Iska, у ImageMagick глобальная проблема с именами файлов нелатинницей. Приходилось запускать его через обёртку, которая переименовывает файл в латинницу, подаёт на вход IM'а, затем переименовывает обратно :-/

Iska 18-06-2011 22:16 1697247

Busla, в каком смысле? Что выдаёт stdout в ANSI (1251)? Это да, есть такое, но не более. А в остальном нормально отрабатывает, что в скрипте, что в утилите «identify.exe».

А у Вас что не срабатывает (у меня старая версия — «ImageMagick 6.3.4»)? Можете привести пример?

Jr.Janitor 21-06-2011 14:29 1698867

Iska, Огромнейшее спасибо!!!
1. Очень интересная библиотека. Жаль, что тяжелая и надо инсталлить, позже попробую их 8-битную портабельную версию.
2. Скачал текущую версию 6.7.0, в ней для отображения ошибок кроме -regard-warnings нужен еще и -verbose.

Мой сменщик помог с батником, закинул все домой РАдмином, запустил, теперь буду ждать результата.
вот такой скрип получился:
Код:

@Echo off
setlocal EnableExtensions

set IM="%ProgramFiles%\ImageMagick-6.7.0-Q8\identify.exe"
set WD="%1"
if not defined WD set WD="%CD%"
set Log="%CD%\%~n0.txt"
set N=0
set T=0
set P=.
set CR=

pushd %WD%
for /f "tokens=1 delims=" %%F in ('dir /a-d /b /s') do call :Check "%%F"
popd
echo Corrupted or unknown formats: %N%/%T%
goto :End

:Check
if not "%P%"=="%~dp1" (set P=%~dp1
echo %~dp1
)
if "%T:~-1%"=="0" set /P nul=%N%/%T%%CR%<nul
set /a T+=1
%IM% -verbose -regard-warnings %1>nul 2>nul || (
echo %~1>>%Log%
set /a N+=1
)
exit /b

:End


Jr.Janitor 29-06-2011 20:47 1703838

Батник пришлось доводить до ума... потерял лишние 2-3 дня - вываливался, гад.
Теперь для экономии времени и нервов, в начале сохраняет каталог в файлик (все в текущем каталоге, так что с поврежденного диска не запускать!), и если файлик имеется, то используется уже готовый (экономится примерно 15 минут времени запуска). Далее добавил срез данных (ну, всего-то 2 параметра - кол-во найденных ошибок и последний проверянный файл по сохраненному каталогу), как в старые добрые времена, когда машины висли каждые 2 часа ;)
Так же улучший отображаемую на экран инфу - тек. каталог, штамп времени и счетчики файлов.
Проверяется уже 4е сутки без сбоев, на вторые сутки устал от воя кулера, запустил Эверест - оказалось, температура проца 81 градус (АМД), диска - 65 (ИБМ). Срочно принял меры, сейчас, температура не поднимается выше 75/56 (проц/диск). Текущая статистика - 3125 битых из 85280 проверянных (всего почти 313тыс). Большая часть по списку - спотыкания об кириллицу - меня особо не беспокоит, ибо не мои это фотки, у меня все имена исключительно латиницей. Через неделю жду окончательный вердикт.

Правленный батник:
Код:

@Echo off
setlocal EnableExtensions

set IM="%ProgramFiles%\ImageMagick-6.7.0-Q8\identify.exe"
set WD="%1"
if not defined WD set WD="%CD%"
set Log="%CD%\%~n0.txt"
set Lst="%CD%\%~n0.lst"
set Stat="%CD%\%~n0.stat"
set N=0
set T=0
set CR=
if exist %Stat% for /f "usebackq tokens=1,2" %%N in (%Stat%) do set N=%%N & set T=%%O
if %T%==0 (set P= ) else set P=skip=%T%

pushd %WD%
if not exist %Lst% dir /a-d /b /s *.jpg>%Lst%
for /f "usebackq %P% tokens=1 delims=" %%F in (%Lst%) do call :Check "%%F"
popd
echo Corrupted or unknown formats: %N%/%T%
goto :End

:Check
echo %N% %T% %date% %time%>%Stat%
if not "%P%"=="%~dp1" set "P=%~dp1" & echo %date% %time%        %~dp1
set /P nul=%CR%%N%/%T%        <nul
set /a T+=1
%IM% -verbose -regard-warnings %1>nul 2>nul
set Err=%ErrorLevel%
if %Err%==1 echo %~1>>%Log% & echo %~1
if %Err%==1 set /a N+=1
exit /b

:End


Iska 30-06-2011 05:44 1704000

Цитата:

Цитата Jr.Janitor
Большая часть по списку - спотыкания об кириллицу »

Busla выше не ответил на мой вопрос. А что у Вас не так с кириллицей?

У Вас задача, оказывается, совсем другая, нежели решал я — Вам нужна была полная проверка всех наличествующих *.jpg файлов. Теперь стало ясно.

dascon 14-07-2011 12:30 1713116

Попробовал последний скрипт с ImageMagick-6.7.1-Q8. 80% провернных фото посчитал корявыми или неизвестными (Corrupted or unknown formats), хотя при просмотре искажений не наблюдаю.

Iska 14-07-2011 16:13 1713330

dascon, а для одиночного файла, одного из тех, что как бы «Corrupted or unknown formats», скрипт из #2 что «говорит»?

dascon 19-07-2011 06:51 1715379

Окошко вываливается, Windows Script Host: "Требуется объект"

Может чего не так делаю. Скрипт записал в файл run.vbs. Запускаю run.vbs image.jpg

Iska 19-07-2011 07:45 1715388

dascon, Вы установили «ImageMagick»?

Если — да, то проверьте, удачно ли была зарегистрирована библиотека:
Код:

<Путь, куда был установлен «ImageMagick»>\ImageMagickObject.dll
и наличествует ли в реестре раздел:
Код:

\HKEY_CLASSES_ROOT\ImageMagickObject.MagickImage.1
Если — нет, то попробовать зарегистрировать её вручную посредством «regsvr32.exe».

P.S. Возможно, Вы брали просто архив («ImageMagick-6.7.1-Q16-windows.zip») и разворачивали из него?! Тогда — да, надо регистрировать библиотеку «ImageMagickObject.dll» самому.

dascon 19-07-2011 08:11 1715396

Скачивал установщик, ImageMagick-6.7.1-0-Q8-windows-dll.exe. Но ImageMagickObject.dll у меня вообще на диске нет.

Iska 19-07-2011 14:42 1715663

dascon, при установке приложения нужно установить соответствующий флажок:

dascon 20-07-2011 06:49 1716083

Цитата:

а для одиночного файла, одного из тех, что как бы «Corrupted or unknown formats», скрипт из #2 что «говорит»?
Name:[image001.jpg] Type:[JPEG] Dim:[640x480x8]

Jr.Janitor 21-07-2011 15:35 1717202

Доклад по предварительным результатм ;)
Возни оказалось в порядок больше, ибо диск совсем начал отваливаться и отследить в растущем отчете, где реальные ошибки, а где тупо нет доступа к файлам - очень сложно.
Кончилось тем, что достал из запасника комплектуху, закупленную еще перед НГ - хотел проапгрейдить домашний сервак и запихнуть его наконец-то на антресоль, но корпусов таких типоразмеров не делают, а самопальный застрял на половине перепиливания (в прямом смысле слова) из другого корпуса. Пришлось собирать в открытом виде, прямо на журнальном столике, потеснив ноут, которому и так было места маловато (теперь для мышей места не осталось совсем, приходится возить их по собственной каленке, или садится дальше на кровать и по покрывалу).
Но и тут оказалась засада - комп глючил, переставал включаться, винда еле встала, но работать так и не начала, провозившись с ней 4 дня - было бросил затею, ибо гарантийный случай налицо, но неисправность еще надо доказать. После пары дней перекура меня толкнула мысль, что глюк больше всего похож на утечку в нескольких местах на массу, но несерьезная такая утечка, чуть-чуть пробивает, ибо ничего не сгорело и пищать об ошибках материнка не собирается, но и работать нормально не хочет. Попробовал держать материнку в руках - и точно, никаких глючков, кладу на родной пакет упаковки - тутже виснет и не грузится, а уходит в бескоенчный цикл включения на пару сек и выключение, пауза и опять включение на пару сек. Серый от злости пошел пить чай и думать, чего бы под материнку подложить - ровного, диэлектрического, но ничего нормального в голову не приходило, а распиливать заначенный лист фанеры 150х150 очень не хотелось (хватит с нас и чиновников-распильщиков)... и тут :angel: мой блуждающий взгляд наткнулся на среднюю разделочную доску для мсява... :ok: размер оказался почти как раз!
Тутже доустановил винду, нашел дрова, поставил ИмаджМэджик, запустил батник... за час статистика показала, что ждать мне снова 4-5 дней, хотя в первом случае диск был на серваке, а проверка шла по сети с ноута образца 2005г. и время было примерно тем же, :lamer: разве что нагрузка проца - 25%... разделил ручками исходный список на 4 равные части и загрузил все 4 ядра. Загрузка 98-99%, все тормозит, но через 2 дня проверка закончилась. На выходе 4 файлика со списками "битых" файлов по 3-6 тыс.строк.
Попробовал проверять файлики из списков ручками, по-очечереди, понял, что тут тоже нужна автоматизация. Сейчас трясу сменщика что-нить придумать, обещал помочь. Думаю, скоро выложу его 2й батничек, для обработки логов.

Iska 21-07-2011 16:10 1717227

По идее, скриптом должно быть быстрее, нежели N раз запускать процесс из командного файла. Ну, а на С/С++ ещё шустрее :).

plvtor 13-08-2011 23:59 1731312

Есть еще такая программка - http://antidupl.narod.ru/russian/ind...=download.html

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

Правда, с приложенной картинкой не справилась, но можно к авторам попробовать обратиться.

vmus 06-02-2014 22:01 2304339

Спасибо за решение с ImageMagick.
То же понадобилось проверить кучу файлов на наличие битых.
С текущей версией ImageMagick проблем с кирилицей у меня не возникло (win7 32bit, ImageMagick-6.8.8-4-Q8-x86-dll.exe ).
Немного переделал bat-скрипт под себя. Выкладываю свой вариант - может кому пригодится.
Код:

@echo off
@setlocal enableextensions enabledelayedexpansion
@SET identify="C:\Program Files\ImageMagick\identify.exe"
@SET workdir=G:\Photos
@SET LOGFILE=C:\test\photo%RANDOM%.log
pushd %workdir%
for /F "tokens=1,2* delims=<" %%a in ('dir *.jpg *.tif /a:-d /b /s') DO (
    echo ***%date% - %time% %%a  >> %LOGFILE%
    %identify% -regard-warnings "%%a"  >> %LOGFILE% 2>&1
    )
popd

Скрипт при работе создает в папке запуска текстовый файл с результатами проверки всех jpg и tif в папке (и подпапках) G:\Photos.
После поиском по этому текстовому файлу по слову corrupt или warn находим или не находим поврежденные файлы.


Время: 21:27.

Время: 21:27.
© OSzone.net 2001-