Скрипт автоматической сортировки фотографий по дате

Изображение пользователя dm.

Накопилось у меня куча неразобраных и разномастных фотографий которые надо было как то разгрести. В ручную и даже с помощью digikam делать это было неудобно и долго.

Пришлось написать небольшой скрипт для сортировки фотографий, который и выкладываю на ваш суд.

Скрипт раскладывает фотографии по каталогам вида гггг/мм, изменяет разрешение и качество в соответствии с заданными параметрами, а так же переименовывает изображения в формат гггг-мм-дд_чч-мм-сс.jpg

На пример: /mnt/DCIM/IMG-20131014112354.jpg -> $HOME/Photo/2013/10/2013-10-14_11-23-54.jpg

Данные о дате снимка ищутся в следующем порядке:

  1. Exif данные (Exif.Photo.DateTimeOriginal и Exif.Image.DateTime)
  2. В названии фотографии. Распознает различные варианты написания даты
  3. Из даты создания файла

При запуске без аргументов обрабатывает текущий каталог и все его подкаталоги. В качестве аргумента можно указать другой рабочий каталог-источник.

НЕ удаляет оригиналы изображений
НЕ увеличивает разрешение
Для работы необходим пакет exiv2 и imagemagick (sudo apt-get install exiv2 imagemagick)

Для установки копируем код скрипта на пример в /usr/local/bin/photo_sort.sh
Даем права на исполнение sudo chmod +x /usr/local/bin/photo_sort.sh
Запускаем в нужной папке с фотографиями.

Комментарии (29)

0
Vorobey - 26 Ноябрь, 2013 - 23:06
Изображение пользователя Vorobey.

Спасибо, классно работает.
Как его остановить?
И как сделать чтоб изображения были оригиннального размера?

ps quality=80 - это величина компрессии или процент ресайза?

0
dm - 27 Ноябрь, 2013 - 08:57
Изображение пользователя dm.

Как его остановить?

CTRL-C во время работы остановит скрипт.

И как сделать чтоб изображения были оригиннального размера?

Убрать из скрипта -resize "$resize"\>. Либо установить размер ресайза на заведомо больший чем ваши фотографии. Скрипт не увеличивает фотографии если указан размер ресайза больше исходного разрешения изображения.

ps quality=80 - это величина компрессии или процент ресайза?

Величина компрессии. Размер ресайза это resize=1600x900

0
Vorobey - 28 Ноябрь, 2013 - 00:08
Изображение пользователя Vorobey.

Хорошо парсит фото. Думал как о страшном сне, что мне придется сортировать фотки и приводить в порядок.

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

0
dm - 28 Ноябрь, 2013 - 20:33
Изображение пользователя dm.

Я просто кидаю файл в каталог с фото и кликаю на нем. как остановить нашел ).

Проще кинуть скрипт на пример в /usr/local/bin/ и не будет необходимости каждый раз кидать скрипт в папку с фотками, достаточно будет просто набрать photo_sort.sh и запустить.

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

0
Vorobey - 28 Ноябрь, 2013 - 20:41
Изображение пользователя Vorobey.

Да так и есть. Просто иногда забываю что куда кидал, и как называется.

0
novocat - 30 Ноябрь, 2013 - 06:39
Изображение пользователя novocat.

Всё прекрасно.
А почему вес увеличивается, если выставить так:
quality=100 # Качество JPG изображения
#resize=1600x900 # Размер после конвертации // закоментил, чтобы не менять размер.

Съемка производилась на Canon EOS 600D Kit.
Оригиналный размер: 5184х3456, 6,9 МиБ
После скрипта: 5184х3456, 10,2 МиБ

0
dm - 30 Ноябрь, 2013 - 10:41
Изображение пользователя dm.

Вес увеличивается по тому, что исходное изображение имело большую степень сжатия (Quality 75 или 80 скорее всего). Конечно фактически качество изображения не улучшиться от выставления меньшей степени сжатия (quality 100) но параметры сжатия jpg меняются и соответственно размер тоже. Подробней про алгоритмы сжатия jpg ищите в интернете, информации достаточно.

Вообще, если нужно просто переименовать фотографии и разложить по папкам не проводя над ними никаких действий, типа изменения разрешения и изменения степени сжатия, то можно просто закомментировать в скрипте строку:

convert -quality "$quality" -resize "$resize"\> -verbose "$file" "$dst_dir/$1/$2/$1-$2-$3_$4-$5-$6.jpg"

и раскомментировать (убрать # из начала строки) строку:

cp -uvp "$file" "$dst_dir/$1/$2/$1-$2-$3_$4-$5-$6.jpg"

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

0
novocat - 30 Ноябрь, 2013 - 14:25
Изображение пользователя novocat.

Спасибо. Еще одна проблема возникла в процессе тестирования скрипта.
«/home/novocat/Pictures/2013/IMG_5932.JPG» -> «/home/novocat/Photo/2013/11/2013-11-10_15-20-21.jpg»
«/home/novocat/Pictures/2013/IMG_5933.JPG» -> «/home/novocat/Photo/2013/11/2013-11-10_15-20-21.jpg»
cp: невозможно создать обычный файл «/home/novocat/Photo/2013/11/2013-11-10_15-20-21.jpg»: Отказано в доступе.
Видимо, при серийной съемке (режим спорт), созданы фотографии с одинаковым временем.
Или в чем-то другом проблема?

0
dm - 30 Ноябрь, 2013 - 15:33
Изображение пользователя dm.

Видимо, при серийной съемке (режим спорт), созданы фотографии с одинаковым временем.

Видимо так. У меня такой проблемы не возникало.

Как быстрое решение, можно из строки
cp -uvp "$file" "$dst_dir/$1/$2/$1-$2-$3_$4-$5-$6.jpg"

убрать ключ -u тогда будут создаваться резервные копии при одинаковых названиях файлов

cp -vp "$file" "$dst_dir/$1/$2/$1-$2-$3_$4-$5-$6.jpg"

0
novocat - 9 Февраль, 2014 - 18:13
Изображение пользователя novocat.

Не работает такой вариант с убиранием ключа -u.
Смотрите:
Время создания IMG_0013.JPG - 09.02.14 23:51
Время создания IMG_0014.JPG - 09.02.14 23:51
Вот лог:
«/home/novocat/123/IMG_0013.JPG» -> «/home/novocat/Photo/2014/02/2014-02-09_16-51-01.jpg»
«/home/novocat/123/IMG_0014.JPG» -> «/home/novocat/Photo/2014/02/2014-02-09_16-51-01.jpg»
Разница создания фото примерно 5-10 секунд.
Возможно как-нибудь доработать скрипт?

0
dm - 11 Февраль, 2014 - 01:02
Изображение пользователя dm.

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

0
novocat - 11 Февраль, 2014 - 19:17
Изображение пользователя novocat.

Протестировал.
Файлы начинает создавать и через 15-20 фотографий процесс зависает.

В консоле выдает: photo_sort.sh: 75: photo_sort.sh: let: not found
В скрипте это: let "a+=1"
0
dm - 11 Февраль, 2014 - 22:42
Изображение пользователя dm.

Поправил скрипт в предыдущем комментарии.

0
Cyber_M - 2 Декабрь, 2013 - 12:48
Изображение пользователя Cyber_M.

Спасибо, очень полезно.

0
Гость - 17 Март, 2014 - 10:31

Спасибо большое! Просто очень нужный скрипт!

0
Гость - 19 Март, 2014 - 21:43

Автору, огромное спасибо, скрипт сохранил мне уйму времени, т.к. у меня "умер" жесткий и фото были восстановлены утилитами, которые просто читают сектора, естественно, что при таком восстановлении, все фото были в одной куче и куча размером более 600 Гб, имена файлов - просто цифры в виде ID :)
Единственное, что я поправил в скрипте для себя, это не копирование фотографии, а её перемещение, т.к. при копировании, на текущем жестком не хватало места физически + при копировании в стеке выдавались ошибки вида:
Error: Upper boundary of data for directory Panasonic, entry 0x0021 is out of bounds: Offset = 0x00000780, size = 8200, exceeds buffer size by 24 Bytes; adjusting the size
Error: Offset of directory Panasonic, entry 0x0025 is out of bounds: Offset = 0x00002788; truncating the entry
и при копировании я не мог оценить, на какие файлы были битыми, а при перемещении, все битые и спорные файлы останутся в папке-куче.

0
Гость - 8 Апрель, 2014 - 18:55

Спасибо за скрипт, немного изменил и тут свою версию выложил.
Я добавил расширения-папки, номер файла оригинала - вместо счетчика что у вас.
также убрал exiv тк не поддерживал его nas, он особо не нужен если загружать новый фотки а не разбирать старые

0
serpt - 25 Декабрь, 2014 - 14:14

Спасибо огромное!

0
Smith2007 - 23 Июль, 2015 - 08:44

Давно искал подобный скрипт.
Спасибо автору.
Вопрос: как модифицировать скрипт для следующей ситуации...
Фото и видео материалы сортирую следующим образом:
Корневая папка/2015/2015-07-20/оригинальное имя файла
PathToPhoto/YYYY/YYYY-MM-DD/original-file-name

При этом файлы надо перемещать.

0
dm - 23 Июль, 2015 - 12:18
Изображение пользователя dm.

Вот эту часть

# Разбиваем полученную дату (гггг мм дд чч мм сс) на фрагменты
  # $1 - Год, $2 - Месяц, $3 - День, $4 - Час, $5 - Минута, $6 - Секунда
  set -- $photo_date

  mkdir -p "$dst_dir/$1/$2" # Создаем структуру папок гггг/мм

  # Копируем фотографию, только если исходный файл новее существующего или отсутствует. При копировании сохраняется дата создания фотографии
  #cp -uvp "$file" "$dst_dir/$1/$2/$1-$2-$3_$4-$5-$6.jpg"

  # Изменяем качество и размер фотографий, переименовываем и копируем в папку назначения
  convert -quality "$quality" -resize "$resize"\> -verbose "$file" "$dst_dir/$1/$2/$1-$2-$3_$4-$5-$6.jpg"

заменить на эту

# Разбиваем полученную дату (гггг мм дд чч мм сс) на фрагменты
  # $1 - Год, $2 - Месяц, $3 - День, $4 - Час, $5 - Минута, $6 - Секунда
  set -- $photo_date

  mkdir -p "$dst_dir/$1/$1-$2-$3"

  # Копируем фотографию, только если исходный файл новее существующего или отсутствует. При копировании сохраняется дата создания фотографии
# cp -uvp "$file" "$dst_dir/$1/$1-$2-$3/$file.jpg"

  # Изменяем качество и размер фотографий, переименовываем и копируем в папку назначения
  convert -quality "$quality" -resize "$resize"\> -verbose "$file" "$dst_dir/$1/$1-$2-$3/$file.jpg"

0
Smith2007 - 23 Июль, 2015 - 13:07

Спасибо за оперативный ответ.

У меня кроме фото-файлов будут еще и видео и мне нужно их просто переместить в соответствующие каталоги без какой либо конвертации и добавления расширения.

0
dm - 23 Июль, 2015 - 17:52
Изображение пользователя dm.

Видео он не обрабатывает.

0
Smith2007 - 23 Июль, 2015 - 20:02

Переменная $file в начале имеет полный путь. Не завелся скрипт.
А с видеофайлами можно просто дату создания брать

После строки #приводим различные вариации к единому виду $photo_date становится пустой.

0
Гость - 25 Январь, 2016 - 01:16

Спасибо! Я к сожалению обнаружил что не иногда не верно определяет дату. Ошибается в месяцах.
Я не сильно разбираюсь в bash - даже наоборот - только учусь.
Долго копал этот скрипт - ошибка тут есть но не могу понять в чем
photo_date=$(echo "$photo_date" | egrep -o -m1 [0-9]\{4\}\([-_:\ ]?[0-9]\)\{10\} | tr -d "\_\-\:\ " | sed 's/\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1 \2 \3 \4 \5 /')

0
dm - 25 Январь, 2016 - 12:59
Изображение пользователя dm.

Привер бы фотографий на которых ошибается. У себя ошибок с определением даты не видел.

0
Гость - 27 Январь, 2016 - 02:08

К примеру те что нашел. В информации о файле нет графы дата съемки как обычно должно быть. есть только дата оцифровки. Но Exif.Photo.DateTimeOriginal и Exif.Image.DateTime определяют дату все равно. Откуда-то берут инфу. Не могли бы вы подсказать как можно взять информацию из поля "дата оцифровки"?
И спасибо за этот скрипт!

0
lyol.val - 27 Январь, 2016 - 20:03

Может, так?
exif:DateTimeDigitized
(относительно двоеточия не уверен...)

0
Гость - 6 Декабрь, 2016 - 04:09

Спасибо за скрипт! а как его заставить просматривать и вложенные папки в директории?

0
dm - 6 Декабрь, 2016 - 11:20
Изображение пользователя dm.

Он и так обрабатывает все вложенные папки.

0
Гость - 21 Май, 2017 - 23:16

Спасибо за Ваш скрипт! а есть ли возможность модернизировать скрипт, чтобы обрабатывать не только JPG, но и другие форматы файлов фотографий, например такие, как PNG?

0
Гость - 21 Май, 2017 - 23:23

Подскажите пожалуйста, в результате работы скрипта (от 11 Февраль, 2014 - 01:02) получен такой результат, что некоторые файлы пишутся в корень директории, как в примере ниже, в файл c именем "--_--_280.jpg"

'/home/nigo/Photos_DUMP/RedFerarri/photo/arhiv_2002_2016/20140910_102311000_iOS.jpg' -> '/home/nigo/Photo///--_--_280.jpg'

В чем может быть причина и можно ли с таким бороться?

Отправить комментарий

CAPTCHA на основе изображений
Введите цифры