Linux - скрипт пакетной группировки фотографий

Для хранения базы своих фотографий раньше использовал пакетную обработку от XnView. Сегодня решил написать скрипт, который будет автоматически разбрасывать мои фотографии в определенную папку с разброской в подпапки по годам.

Имеем Ubuntu 16.04. Для работы скрипта группировки нам понадобится exiv2 и imagemagick. Для их установки выполните команду:

sudo apt-get install exiv2 imagemagick

Далее, приведу сам скрипт с комментариями по ходу

#!/bin/bash
# Скрипт раскладывает фотографии по каталогам вида гггг/мм, изменяет разрешение и качество в
# соответствии с заданными параметрами, а так же переименовывает изображения в формат
# гггг-мм-дд_чч-мм-сс.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 (sudo apt-get install exiv2)
##################################

src_dir=${1-`pwd`}	# По умолчанию используется текущий каталог
dst_dir=$HOME/PHOTO	# Каталог в который будут скопированны обработанные фотографии

quality=95  		# Качество JPG изображения
# resize=1600x900		# Размер после конвертации - раскомментируйте эту строку, и закомментируйте строку ниже, если хотите задать размеры изображения
resize=100% # оставляем 100%-ный размер

mkdir -p "$src_dir/../$(basename $src_dir)_done"  # создаем папку, рядом с обрабатываемой, в которую поместим резервную копию изображения

# Ищем JPG файлы в указанной папке и всех подпапках!
find "$src_dir" -iname "*.jpg" | sort | while IFS= read -r file ; do

  # Пробуем взять дату из Exif.Photo.DateTimeOriginal или Exif.Image.DateTime
  for photo_date in "Exif.Photo.DateTimeOriginal" "Exif.Image.DateTime" ; do
    photo_date=$(exiv2 -g "$photo_date" -Pv "$file")
    if [ -n "$photo_date" ] ; then  # Если дата найдена, прекращаем перебор
      break
    fi
  done

  if [ -z "$photo_date" ] ; then # Если в exif дата не найдена ищем в названии файла

    # Ищем дату в названии файла и приводим её к виду ггггммддччммсс
    photo_date=$(basename "$file" ".jpg" | egrep -o -m1 [0-9]\{4\}\([-_:\ ]?[0-9]\)\{10\})


      if [ -n "$photo_date" ] ; then

	# Приводим дату к виду гггг:мм:дд чч:мм:сс для корректного добавляения в exif
	photo_date=$(echo "$photo_date" | tr -d "\_\-\:\ " | sed 's/\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1:\2:\3 \4:\5:/')

	# Добавляем дату из названия файла в exif
	exiv2 -M"add Exif.Image.DateTime Ascii "$photo_date"" "$file"

      else # Если даты в названии не нашли, берем дату изменения (создания) файла
	photo_date=$(date +"%Y:%m:%d %T" -r "$file")
	#exiv2 -M"add Exif.Image.DateTime Ascii $photo_date" "$file"
      fi
  fi

  # Приводим различные вариации даты к единому виду гггг мм дд чч мм сс
  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 /')

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

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

  # Копируем фотографию, только если исходный файл новее существующего или отсутствует. При копировании сохраняется дата создания фотографии
  #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"
  convert -quality "$quality" -resize "$resize"\> -verbose "$file" "$dst_dir/$1/$1-$2-$3/$(basename $file)"

  # Устанавливаем дату создания файла такую же как и дата в exif
  # touch -t "$1$2$3$4$5.$6" "$dst_dir/$1/$2/$1-$2-$3_$4-$5-$6.jpg"
  touch -t "$1$2$3$4$5.$6" "$dst_dir/$1/$1-$2-$3/$(basename $file)"


  mv $file $src_dir/../$(basename $src_dir)_done/$(basename $file)

done

exit 0

Самое главное, чтобы у вашего фото-устройства была корректно задана дата :)

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

sh /path-to-script.sh

Для того чтобы посмотреть полный набор exif-данных, можно воспользоваться инструментом exiftool:

exiftool image-path

Для установки данного инструмента, необходимо выполнить команду:

sudo apt install libimage-exiftool-perl
Количество показов: 2065
02.06.2018

Возврат к списку

Если вам была полезна статья можете отблагодарить автора:
Ethereum:

0x16Df809287333C49D3A237296C6248A6c08702Bc

Разработка сайта

Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин - что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки...

Сопровождение сайта

Вы можете подать заявку на сопровождение вашего сайта на базе 1С-Битрикс. Сопровождение включает в себя: проверка актуальности обновлений сайта, проверка актуальности резервной копии, консультации по сайту. Опишите в заявке, какие еще объемы планируются на сопровождении и на какой срок вы планируете заключить договор на сопровождение - мы подберем подходящий вам бюджет на сопровождение

Работы по сайту

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