Битые картинки в галерее с фотоаппаратов, камер, телефонов и прочих средств... Наверное это знакомо каждому. И большинство из нас не знает масштаба трагедии, пока не наткнётся на парочку таких замечательных картинок, наподобие той, что я прикрепил в шапке. К слову эту картинку я специально попортил, открыв в текстовом редакторе и добавив один символ в середину файла. Понятно, что исправить такой байт - проблема та ещё, т.к. требует глубокого семантического анализа и не всегда восстановление возможно. Однако, подобных проблем можно избежать путём резервного копирования и использования файловых систем, поддерживающих "лечение" поломанных байтов данных. Но, начнём с простого - как определить, какие файлы поломаны, чтобы восстановить их из резервной копии.
Итак, озадачившись вопросом поиска файлов, которые по тем или иным причинам повредились, я создал небольшой скрипт, который позволяет выявить перечень этих файлов в удобном виде.
Для этих целей я воспользовался возможностями библиотеки imagemagick, которая является главной зависимостью моего скрипта. Среди утилит, входящих в Imagemagick, есть утилита identify-im6 которая в обычной жизни используется для чтения информации из файлов изображений. Однако, побочным выводом этой команды, является определение повреждений в файлах. В частности, в выводе команды
$identify-im6 -regard-warnings -verbose image.jpg
в случае наличия повреждений, проявляется строки вида:
identify-im6.q16: Corrupt JPEG data: premature end of data segment `image.jpg'
с перечислением проблем. Собственно это я и решил отловить.
Получился вот такой скриптик, который можно взять и пользоваться:
#! /bin/bash
#Ask for path
helpFunction()
{
echo ""
echo "Использование: $0 -p 'директория для проверки' -o 'файл отчёта' "
echo -e "\t-p Путь к проверяемым файлам"
echo -e "\t-o Путь к файлу отчёту"
exit 1
}
while getopts "p:o:" opt
do
case "$opt" in
p ) folderToCheck="$OPTARG";;
o ) outputFile="$OPTARG";;
? ) helpFunction ;;
esac
done
if [ -z "$folderToCheck" ] || [ -z "$outputFile"]
then
echo "Введите путь к директории для проверки и файл отчёта"
helpFunction
fi
echo "Проверяем файлы изображения с помощью ImageMagick в $folderToCheck"
counter=1
Red="\033[0;31m" # красный
Green="\033[0;32m" # зелёный
Color_Off="\033[0m" # сброс текста
cd "${folderToCheck}"
# Перечисление файлов
count=$(find "$(pwd)" -type f -iname "*.jpg" -o -iname "*.jpeg" | wc -l | xargs)
# Поиск всех файлов и обработка
find "$(pwd)" -type f -iname "*.jpg" -o -iname "*.jpeg" | while read -r line ; do
result=$(identify-im6 -regard-warnings -verbose "${line}" > /dev/null 2>&1&&echo $?)
if [[ "$result" == *"0"* ]] ; then
echo -e "OK $line" >> /dev/null
status="${Green}"
else
echo -e "БИТЫЙ ФАЙЛ $line" >> $outputFile
status="${Red}"
fi
echo -e "${status} Файл ${counter} из ${count}${Color_Off} → ${line##*/}"
counter=$(( $counter + 1 ))
done
echo "Запись файла ${outputFile}"
echo "-------------- ГОТОВО --------------"
Это можно скопировать в файл вида find-crptd-img.sh, добавив возможность исполнения командой $chmod +x find-crptd-img.sh. После этого пользоваться скриптом можно будет с помощью команды:
$find-crptd-img.sh -p 'путь к папке с картинками' -o отчёт.txt
После чего скрипт пройдёт в директорию и начнёт читать подряд все файлы изображений формата JPEG (возможно в будущем я проапгрэйжу скрипт до проверки и других форматов, но пока так) и записывать в файл "отчёт.txt" битые файлы из директории.
Смею заметить, что у этого скрипта есть пара косяков - один из них это то, что в битые файлы запишутся модифицированные с помощью некоторых программ изображения, которые некорректно записали данные в файл. В частности это касается сшитых вручную панорам. Ну и вторая - то, что степень битости файлов никак не определена - возможно это коснулось только атрибутивной части и само изображение выглядит нормально. Тут уж просто стоит взглянуть на эти файлы своими глазами прежде, чем их удалять.
В общем, как-то так, удачного использования.
Комментариев нет:
Отправить комментарий