Организация архива фотографий (обновлено)


Отредактировано 2017.02.09


В данной статье я постараюсь описать методы каталогизации, обработки и резервного копирования моего фотоархива.

Я не являются профессиональным фотографом, поэтому вопросы хранения и обработки коммерческой фотографии не затрагиваю.

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

Структура каталогов для хранения архива фотографий

Иерархия каталогов верхнего уровня

[D] MyPhotos
    [D] -for-sort-
    [D] -id-
    [D] -notes-
    [D] -tests-
    [D] Groups
    [D] Dates

Содержание каталога “-for-sort-

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

[D] Canon350D
    [F] IMG_1001.JPG
    [F] IMG_1001.CR2
[D] Canon450D
    [F] IMG_2001.JPG
    [F] IMG_2001.CR2

Содержание каталога “-id-

Для каждого автора, чьи фотографии присутствуют в архиве, создается отдельный каталог с информацией о нем. Имя этого каталога является уникальным идентификатором автора - AuthorId.

[D] IvanPetrov
    [F] readme.txt
[D] PetrIvanov
    [F] photo.jpg
    [F] links.txt

Содержание каталога “-notes-

Каталог с различными фото-заметками, например: объявления, расписания автобусов и т.п.

[F] Расписание_Трамвая_13.jpg
[F] Выходные_Дни_Август_2016.jpg
[D] Цены_На_Радиодетали
    [F] IMG_0001.JPG
    [F] IMG_0002.JPG

Содержание каталога “-tests-

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

Для каждого устройства создается отдельный каталог, который совпадает с его моделью.

Пример оформления тестов:

[D] Canon600D
    [D] 2016.05.02-Canon600D.DustTest
        [F] IMG_0123.CR2
    [D] 2016.07.01-Canon600D.HotPixelTest
        [F] IMG_0456.CR2

Содержание каталога “Groups

Каждая группа фотографий имеет свой отдельный каталог.

[D] Birthday
    [D] 2011.09.23-Birthday.IvanIvanov
[D] Family
    [D] 0000.00.00-Family.Archive
    [D] 2002.03.10-Family.School
[D] Dance
    [D] 2015.07.18-Dance.OpenAir
[D] IT
    [D] 2014.03.15-HardwareFreedomDay.Novosibirsk
    [D] 2016.05.14-LugNsk.Picnic

Содержание каталога “Dates

Фотографии, которые остались без группы, сортируются по дате.

[D] 0000
    [D] 0000.00.00-Animals
[D] 2012
    [D] 2012.03.17-Walk.Novosibirsk
    [D] 2012.09.22-Stuff.Fruits
[D] 2016
    [D] 2016.02.27-Selfie
    [D] 2016.07.25-NightSky

Каталог с фотографиями

Каталог с фотографиями (сокращенно КФ) содержит набор файлов(не обязательно фотографий), которые объеденны общей тематикой. Как правило, в один и тот же день у меня может быть несколько КФ.

Для примера:

В целом, формат имени КФ свободный. Но я стараюсь записывать ключевые слова через точку и более значимые помещать левее. В дальнейшем это облегчает поиск.

Указание авторства фотографий

В моем архиве находятся не только мои фотографии, но и фотографии других людей. Для того, чтобы как-то их различать в каждом КФ я создаю отдельный каталог с именем автора (AuthorId).

Но есть пара исключений:

Пример:

[D] **Dates**
    [D] 2012
        [D] 2012.03.17-Walk.Novosibirsk   # Мои фотографии
            [F] IMG_0001.JPG     
        [D] 2012.05.17-Walk.Tomsk
            [D] AlekseyDurachenko         # Мои фотографии
                [F] IMG_0002.JPG
            [D] IvanPetrov                # Автор "Иван Петров"
                [F] IMG_0003.JPG
            [D] Unknow                    # Автор фотографий неизвестен
                [F] IMG_0004.JPG
[D] **Groups**
    [D] Birthday
        [D] 2001.01.11-Birthday.PetrIvanov       # Автор фотографий неизвестен
            [F] IMG_0005.JPG                     
        [D] 2011.09.23-Birthday.IvanPetrov
            [D] AlekseyDurachenko                # Мои фотографии
                [F] IMG_0006.JPG
            [D] IvanPetrov                       # Автор "Иван Петров"
                [F] IMG_0007.JPG
            [D] Unknow                           # Автор фотографий неизвестен
                [F] IMG_0008.JPG                     

Содержимое каталога с фотографиями

[D] audio
    [F] REC_0001.WAV
[D] raw
    [D] .git
    [D] processed
    [D] uploaded
        [D] vk
        [D] flickr
    [F] .gitignore
    [F] IMG_0001.CR2
    [F] IMG_0001.CR2.xmp
    [F] IMG_0002.CR2
    [F] IMG_0003.CR2
    [D] make_all_photos.sh
    [D] make_photos_for_vk.sh
    [D] make_photos_for_flickr.sh
    [D] uploaded.txt
[D] video
    [F] VID_0001.MP4
[F] IMG_0001.JPG
[F] IMG_0002.JPG
[F] IMG_0003.JPG
[F] track.gpx

Каталогизация фотографий

После того, как фотографии разложены по каталогам необходимо отредактировать их метаданные. Для этой цели я использую digikam. Он позволяет записать метаданные прямо в файлы изображений. Да и просто является удобным менеджером фотографий.

Обычно, я добавляю следующую информацию:

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

exiftool -overwrite_original -geosync=+07:00:00 -geotag=track.gpx *.JPG

Примечание: я редактирую метаданные исходных JPEG файлов, RAW файлы не трогаю.

Обработка фотографий

Обработкой фотографий я занялся совсем недавно, поэтому процедуры еще не совсем устоявшиеся и в дальнейшем будут усовершенствоваться.

Первым делом я просматриваю фотографии в формате JPEG и отмечаю в digiKam желтыми флажками те, чьи RAW будут обработаны в darktable.

После того, как я завершил обработку RAW файла я помечаю его пятью звездами в darktable. Эта информация нужна для того, чтобы скрипт make_all_photos.sh, понял, что данный файл является завершенным и из него можно создавать JPEG файл максимального качества. JPEG файл максимального качества автоматически помечается зеленым флажком.

Фотографии, которые предназначены для Вконтакте прописываются вручную в скрипте make_photos_for_flickr.sh. А для Flickr в make_photos_for_flickr.sh.

Чтобы сохранить историю изменений файлов я создаю в каталоге raw локальный git репозиторий.

Резервное копирование

В качестве носителя для резервных копий я использую внешний жесткий диск с файловой системой ext4.

Перед созданием резервной копии я рассчитываю контрольные суммы всех файлов и сохраняю их в checksum.md5.

find . -type f -print0 | xargs -0 md5sum > ./checksum.md5
[D] MyPhotos
    [D] -for-sort-
    [D] -id-
    [D] -notes-
    [D] -tests-
    [D] Groups
    [D] Dates
    [F] checksum.md5

Затем подключаю внешний жесткий диск и запускаю скрипт backup.sh.

После каждого запуска backup.sh создается полная копия содержимого MyPhotos. Благодаря тому, что файловая система позволяет создавать жесткие ссылки будут скопированы только измененные файлы. Это позволяет сэкономить место на внешнем жестком диске(и, как следствие, увеличить число снапшотов) а так же ускорить время создания резервной копии.

Программное обеспечение используемое для обработки и каталогизации фотографий

Исходные коды вспомогательных скриптов и файлов

Скрипт make_all_photos.sh

Скрипт создает финальные JPEG обработанных RAW в максимальном качестве, помечает их зеленым флажком, а так же копирует метаданные из исходных JPEG файлов.

#!/bin/bash

DST_PATH=`pwd`/processed

mkdir -p ${DST_PATH}

function export_photo {
    echo "Processing $1"
    # export raw file to jpeg file
    darktable-cli $1 $1.xmp ${DST_PATH}/${1%%.*}.jpg
    # remove rating from the jpeg file, because the darktable-cli create it, but i don't need it!
    exiftool -overwrite_original -rating=0 -IFD0:Rating=0 -xmp:Rating=0 -IFD0:RatingPercent=0 -xmp:RatingPercent=0 ${DST_PATH}/${1%%.*}.jpg
    exiftool -overwrite_original -rating= -IFD0:Rating= -xmp:Rating= -IFD0:RatingPercent= -xmp:RatingPercent= ${DST_PATH}/${1%%.*}.jpg
    # copy metadata from the original jpeg file
    if [ -f ../${1%%.*}.JPG ];
    then
      exiftool -overwrite_original -TagsFromFile ../${1%%.*}.JPG  "-all:all>all:all" ${DST_PATH}/${1%%.*}.jpg
    else
      exiftool -overwrite_original -TagsFromFile ../${1%%.*}.jpg  "-all:all>all:all" ${DST_PATH}/${1%%.*}.jpg
    fi
    # mark photo as PickLabel=3 (green flag)
    exiftool -overwrite_original -orientation= -xmp:PickLabel=3 ${DST_PATH}/${1%%.*}.jpg
}


# export all photos with .xmp files and rating "5"
for i in *.xmp; do
  RATING=`exiftool -xmp:Rating -s -s -s $i`
  ACCEPT="5"
  if [ "$RATING" == "$ACCEPT" ]
  then
      export_photo ${i%.*}
  fi;
done;

Скрипт make_photos_for_vk.sh

Скрипт создает JPEG файлы предназначенные для ВКонтакте. Разрешение изображений уменьшается до 1280х1024, а все метаданные удаляются.

#!/bin/bash

MAX_WIDTH=1280
MAX_HEIGHT=1024
DST_PATH=`pwd`/uploaded/vk

mkdir -p ${DST_PATH}

function export_photo {
    echo "Processing $1"
    darktable-cli $1 $1.xmp ${DST_PATH}/${1%%.*}.jpg --width ${MAX_WIDTH} --height ${MAX_HEIGHT}
    exiftool -overwrite_original -all= ${DST_PATH}/${1%%.*}.jpg
}

# list of the photos
export_photo P9086662.ORF
export_photo P9086669.ORF
export_photo P9086675.ORF
export_photo P9086682.ORF
export_photo P9086690.ORF
export_photo P9086697.ORF

Скрипт make_photos_for_flickr.sh

Скрипт создает JPEG файлы предназначенные для Flickr.

В фотографиях остается минимум метаинформации:

Так же в фотографию добавляется информация о лицензировании.

#!/bin/bash

DST_PATH=`pwd`/uploaded/flickr

mkdir -p ${DST_PATH}

function mark_cc_by_sa {
    exiftool \
    -by-line="Aleksey Durachenko" \
    -CopyrightNotice="(c) Aleksey Durachenko; Licence: Creative Commons BY-SA 4.0 International (https://creativecommons.org/licenses/by-sa/4.0/)" \
    -Artist="Aleksey Durachenko" \
    -Copyright="(c) Aleksey Durachenko; Licence: Creative Commons Attribution-ShareAlike 4.0 International (https://creativecommons.org/licenses/by-sa/4.0/)" \
    -XMP-cc:License="https://creativecommons.org/licenses/by-sa/4.0/" \
    -overwrite_original $1
}


function export_photo {
    echo "Processing $1"
    # export raw file to jpeg file
    darktable-cli $1 $1.xmp ${DST_PATH}/${1%%.*}.jpg
    # remove all metadata for sercurity
    exiftool -overwrite_original -all= ${DST_PATH}/${1%%.*}.jpg

    # copy metadata from the original jpeg file
    if [ -f ../${1%%.*}.JPG ];
    then
        exiftool \
          -overwrite_original \
          -TagsFromFile ../${1%%.*}.JPG \
          -gps:all \
          -model -make -lensmodel \
          -iso -fnumber -exposuretime -apterture -focallength -datetimeoriginal -modifydate -creatdate \
          ${DST_PATH}/${1%%.*}.jpg
    else
        exiftool \
          -overwrite_original \
          -TagsFromFile ../${1%%.*}.jpg \
          -gps:all \
          -model -make -lensmodel \
          -iso -fnumber -exposuretime -apterture -focallength -datetimeoriginal -modifydate -creatdate \
          ${DST_PATH}/${1%%.*}.jpg
    fi

    # apply license
    mark_cc_by_sa ${DST_PATH}/${1%%.*}.jpg
}


# list of the photos
export_photo P8186449.ORF
export_photo P8186483.ORF
export_photo P8186485.ORF
export_photo P8186486.ORF
export_photo P8186488.ORF
export_photo P8186494.ORF
export_photo P8186507.ORF
export_photo P8186516.ORF
export_photo P8186520.ORF
export_photo P8186522.ORF

Скрипт backup.sh

Скрипт для создания резервной копии фотоархива.

#!/bin/bash
set -e
set -x

SUBDIR=MyPhotos
SRC_PATH=/home/user/$SUBDIR/
DATE=`date "+%Y%m%d_%H%M%S"`
CUR_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

FILE=`find $CUR_DIR/$SUBDIR -mindepth 1 -maxdepth 1 -type 'd'  | sort -r | head -1`
if [ "$FILE" ]; then
  cp -al $FILE $CUR_DIR/$SUBDIR/$DATE
else
  mkdir -p $CUR_DIR/$SUBDIR/$DATE
fi

rsync -a --delete --numeric-ids --no-relative --delete-excluded $SRC_PATH $CUR_DIR/$SUBDIR/$DATE/.

Файл .gitignore

*.ORF
*.orf
*.CR2
*.cr2
*.DNG
*.dng
*.JPG
*.jpg
.sha1.sum
.par2
processed
uploaded

UPD: добавлен скрипт подготовки фотографий для Flickr