После покупки цифрового фотоаппарата и рождения детей стало появляться большое количество фотографий, а учитывая, что жена с фотоаппаратом почти не расставалась и старалась запечатлеть все «важные» детские моменты, фотографий стало появляться ОЧЕНЬ много. Пришло время навести порядок.
Дисклеймер: вообще-то это должна была быть статья про Face Recognition, но так как исторически я начал наведение порядка с раскладывания по папкам, пришлось написать вступление, а поскольку получился такой лонгрид, что я и сам бы читать не стал, то решил разбить на две части. Итак, если вам хочется про Face Recognition, то смело пропускайте эту статью и ждите следующую.
Изначально, как и у многих наверное, фотографии просто скидывались на диск в папки с именами вида «День рождения Алисы 2010», но быстро стало ясно, что далеко не все события можно назвать так, чтобы было понятно (была бы куча папок «Алиса ест», «Алиса сидит», «Алиса идет») да и навигация по таким папкам не очень удобна.
За много лет я испробовал разные программы для работы с фотоальбомами (например, Picasa и ей подобные, с просмотром по датам, красивыми эффектами и т.д.) вот только была одна проблема, когда очередная программа «умирала» или возникало желание перейти на другую, то оставалась гора совершенно несортированных фотографий с именами типа PICT1234.JPG. В общем, стало ясно, что за основу создания каталога надо использовать, то, что относительно постоянно, а именно файловую систему. Так родилась «гениальная» структура папок и именований файлов:
Год/Год-Месяц-День (краткое описание)/Год-Месяц-День_Час-Минута-Секунда.ЖПГ
Такая структура позволяла, во-первых, быстро находить фотографии по датам и событиям привязанным к датам, во-вторых, исключала какие-либо дубликаты имен, что удобно и при последующей обработке и при передаче фотографий кому бы то ни было.
Благо цифровой фотоаппарат сохраняет метаинформацию о дате и времени съемки. Осталась самая малость: научиться переносить кучу файлов с флешки на компьютер, используя данную метаинформацию. На помощь пришла популярная тогда в наших краях программа ACDSee, там всего за один десяток кликов можно было переименовать файлы в нужный формат, а уж раскидать по папкам было несложно. Но как говорится — лень двигатель прогресса, и тогда на свет появился не менее «гениальный» скрипт (в то время еще bat и под «виндоус»), делающий подобную операцию.
Все текло, все менялось, со временем медиатека переехала на линукс, да еще и на сервер (т.е. отдельный компьютер без монитора), а фотографий становилось все больше, так как и детей стало больше, да и сами дети тоже стали фотографировать. Пришлось «расчехлить свой питон» и создать нечто более удобное, вот об этом я и хочу тут немного рассказать.
Коротко весь процесс можно разбить на пять этапов:
Найти файлы
Извлечь метаинформацию
Переместить
Повернуть
Дети и жена не хотят пользоваться консолью (внезапно, да?)
С поиском файлов все более-менее ясно, тут справится любой школьник, делающий первые шаги в Python: os.walk и иже с ним ему в помощь.
А вот с метаинформацией не все так просто. К сожалению, не все фотоаппараты выставляют EXIF и прочие метаданные. Как быть? Да, случается что информацию не извлечь никак, но часто есть подсказки, во-первых, атрибуты файла, а во-вторых имя. Многие фотоаппараты и смартфоны зашивают дату и время в имя файла. Например, IMG20180413173249204.jpg или video2017-12-28T22.13.03.mp4
Как показал опыт работы с моим набором медиа файлов, наиболее надежный источник времени съемки это EXIF, на втором месте — имя, а уж на третьем, атрибуты файла (при переписывании, например, по ftp или smb они вполне могут потеряться)
Для извлечения метаданных я использовал библиотеку exiftool. Она позволяет извлекать метаданные из всех возможных форматов, не только из EXIF, с видео и аудиофайлами она тоже отлично работает. Вычисление даты по имени файла сделал своими средствами (regexp и все такое), атрибуты файла же извлекаются стандартным инструментарием (os.stat).
Перемещение файлов можно делать «кроссплатформенно» с помощью shutil.move, а можно через вызов системной утилиты mv. К сожалению, кроссплатформенный способ работает очень медленно и импорт флешки на 32 ГБ, занимает около получаса, так что, если нужна скорость, то лучше использовать вызов системной утилиты, хоть это и не очень красиво.
Многие современные фотоаппараты сохраняют ориентацию камеры во время съемки и многие программы для просмотра изображения умеют этот тег читать, но, к сожалению, далеко не все. Так что лучше просто повернуть сразу все фотографии с учетом этого атрибута. Здесь есть свои тонкости. Во-первых, после поворота необходимо этот тег удалить (иначе будет двойной поворот в тех программах, которые тег читают), во-вторых, не хочется терять качество про повторном сохранении JPEG (к счастью JPEG поддерживает lossless rotation, но многие стандартные библиотеки работы с изображениями об этом не знают). В начале я сделал все это руками, а потом нашел отличную утилиту, которая делает все это сразу и как надо: exiftran. Так что сейчас просто вызывается она.
Казалось бы, все готово. Написал скрипт, вызвал из консоли:
photo-importer /mnt/multimedia/Import
и вот оно счастье! Но не совсем так, с начала надо открыть консоль, зайти по ssh на сервер, примонтировать флешку, найти путь монтирования, набрать команду… В общем, на этом выяснилось, что импортировать так фотки буду только я сам и то по настроению.
Пришлось вспомнить азы «ХуперТекстМаркапЛенгвич», «ЖабаСкрипта» и тому подобного и написать веб-интерфейс с соответствующей ему серверной частью.
По javascript мне рассказать особо нечего, разве что то, что я использовал горячо любимые мной библиотеки bootstrap и jquery.
А вот в серверной части немного больше интересного. Например, была задача обойтись без внешнего веб сервиса (да, у меня на сервере стоит Апач, но ведь не у всех так). Благо питон предоставляет отличные возможности для написания standalone веб сервера. Я воспользовался библиотекой http.server.
Второй интересный момент — это работа с флешками. Тут на помощь пришла утилита pmount, с помощью которой можно легко монтировать внешние носители. Единственное, что осталась, так это проблема распознавания внешних носителей. В первых версиях я просто жестко «зашил» имена нужных блочных устройств в конфиг. Но, как говорится: «Шурик, это же не наш метод!» так что пришлось немного покопаться в устройствах линукса и выяснилось, что есть файл /sys/block/[имя_устройства]/removable
который содержит 1 или 0 в зависимости от того, является ли носитель внешним. А дальше — дело техники.
В итоге получился милый и лаконичный интерфейс, пригодный для использования даже с телефона, где за пару кликов можно импортировать данные с флешки, причем сразу в нужное место и с правильными именами.
А что же консоль? А консоль осталась для кастомных потребностей: прислал кто-то фотки или при наведении порядка в архиве.
Плюс там есть дополнительные возможности, например просто переименовать и повернуть файлы без перемещения.
Если кому интересны детали реализации более подробно, все исходники доступны тут.
Не думаю что эта статья кому-то «открыла Америку», но думаю может послужить примером каким образом немного автоматизировать домашнюю рутину.
В следующей статье расскажу про свои опыты с Face Recognition и про то, что из этого вышло.
indocoder
Дам сразу про-совет. Используйте Год/Месяц. По дням — слишком мелко. Создаете себе лишнюю работу по кликанью в папку каждый день.
Сейчас это может и не так важно, но через лет 10, когда память притупится — будете благодарны что раскидали по бОльшим временным промежуткам.
sashacmc Автор
Спасибо за совет, но это все же зависит от количества фотографий. Миллион в заголовке, это не фигурально их на самом деле миллион (если точнее миллион был пройден уже пару лет назад), ну а сам описанный период это около 16 лет. Простой расчет показывает, это >5000 фотографий в месяц. Так что мне удобнее по дням, но в настройках скрипта можно и по месяцу выставить.
Ну и да, просто на каждый день я давно уже не тыкаю (ну кроме тех случаев когда хочется посмотреть конкретную памятную дату вроде дня рождения или нового года), но об этом уже в следующей статье.
DrPass
Я уже проходил этот этап. Заполнял метаинформацию, каталогизировал. Знаете, в чём прикол? Уже лет пять туда никто не заглядывает, и я в том числе. Ну т.е. по инерции мы там всякие события и сейчас фотографируем, но уже каталогом не заморачиваемся, и жизнь фотографий сразу после того, как их отправили бабушкам/дедушкам/тётушкам/подругам заканчивается, как и когда-то давно — в папке с названием «год, месяц, событие». А все потребности «глянуть, как там дитё росло» с лихвой закрываются гуглофоточками на телефоне, благо, эта гадость со своей нейросеткой сама удачно угадывает, что бы подсунуть для воспоминаний. Более того, у меня как-то винт посыпался с фотками. Думаете, кто-то заметил потери?
RRRoma
я на детские дни рождения на телеке включаю слайдшоу за последние 3-4 года — всем нравится
DrPass
Вот это как раз одна из штук, которые автоматически делают гуглофоточки :)
Layan
У гуглфоточек есть один огромный недостаток: данные пользователю не принадлежат. Гугл вполне себе может в один момент заблокировать доступ ко всему аккаунту.
DrPass
Ну заблокирует, пусть блокирует, локальные копии-то никуда не денутся.
3aBulon
Да, и еще они скоро всем порежут бесконечное кол-во фоток, в обычном качестве. Плати или остаешься без добавления новых фоток.
p_fox
А не проще научиться не фотографировать всё подряд и не захламлять память мусором?
nochkin
Почему фотографирование всего подряд это так плохо? Я так тоже делаю и не вижу проблем.
Ведь «захламляется» у меня, а не у других. Какая им разница на что я использую свободное место?
Focal
Хотел спросить по поводу видеороликов. Такой же принцип структур папок и именований?
sashacmc Автор
Да видео ролики и аудиозаписи (их тоже много) точно также.
Porohovnik
Так наоборот, например по дню очень легко определить что фотки были сделаны, скажем, на дне рождение, на новый год,8 марта и прочее и прочее...
И насчёт лет через десять… то что в колекции раскидано по конкретным событиям(а это и есть привязка к дня) упрощает поиск намного сильнее, ибо иначе вообще теряешься в этой коллекции...
werwolflg
Так тогда лучше как раз события выделять в отдельные папки с названием события, все остальное проще по месяцам хранить. Потому что дни забываются, а месяц проще вспомнить когда было то или иное событие через несколько лет.
shoorick
У меня фотки раскладываются по дням, иногда объединяю соседние дни, иногда наоборот — внутри одного дня выделяю события:
Память притупляется, но точность в один день — подходящая. Архиву больше 20 лет, из них почти 17 — с достаточно большим числом фотографий.