- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF129:gphoto
Материал из Linuxformat.
- gPhoto Управляйте своим фотоаппаратом со своего компьютера
Содержание |
gPhoto: Дрессура для камеры
- Установить Linux на фотоаппарат кажется неплохой идеей, но Андрей Боровский пойдет другим путем.
Зайдите на любой фотофорум, и вы найдете тред о том, почему «мыльница» – не настоящий фотоаппарат, в отличие от «зеркалки». Мы же рассмотрим ситуацию, когда «мыльница» не то чтобы лучше, но, как минимум, интереснее. Когда фото- и видеокамеры научились подключаться к компьютеру, группа ведущих разработчиков фото- и видеооборудования создала протокол PTP (Picture Transfer Protocol – протокол передачи изображений). Основная задача PTP, как следует из его названия, передача изображений между камерой и компьютером, но этим его возможности не исчерпываются. PTP позволяет не только перекачивать изображения из одного хранилища в другое, но и устанавливать настройки фокуса и экспозиции камеры, делать снимки и даже смотреть на мир «глазами камеры», используя механизм предпросмотра изображений. Попросту говоря, если ваша камера поддерживает PTP, ею можно управлять с компьютера.
Не так быстро!
Это были хорошие новости. Плохая новость такова, что далеко не все фото- и видеокамеры умеют работать с PTP. С самого начала у PTP был серьезный конкурент – стандарт USB Mass Storage, который позволяет представить любое USB-устройство, имеющее хранилище данных, как внешний USB-диск (именно его реализуют брелки, внешние жесткие диски и прочая периферия). Стандарт USB Mass Storage не обладает широтой возможностей протокола PTP, зато он удобнее при передаче данных с устройства в компьютер (а это в основном и требуется владельцам цифровых камер).
Неудивительно, что производители цифровой фотоаппаратуры реализовали в своих изделиях USB Mass Storage, а вот про PTP многие «забыли». Как ни странно, поддержка PTP чаще встречается в относительно дешевых «мыльницах», чем в дорогих зеркальных аппаратах; и если вы хотите экспериментировать с PTP, имеет смысл приобрести модельку за пару сотен условных единиц (что я и сделал). Если вы уже решили бежать за новой «мыльницей», дочитайте эту статью хотя бы до описания утилиты gphoto2.
По умолчанию все фотокамеры работают в режиме Mass Storage, и в режим PTP их нужно включать специально (рис. 1). Но камера, поддерживающая PTP – это только полдела. Чтобы поразить мир чудесными снимками, созданными под управлением компьютера, понадобится специализированное ПО.
Операционная система Windows умеет работать с PTP, однако предоставляет лишь базовые возможности, такие как установка режима фотовспышки и снимок нажатием кнопки на компьютере (как будто ее нельзя нажать на фотоаппарате). В Сети можно найти множество условно-бесплатных и просто бесплатных программ для Windows, использующих возможности PTP более широко, но самое сильное желание, которое возника ет при знакомстве с этими приложениями – написать собственное, которое бы делало именно то, что надо мне. Не удержусь от того, чтобы не сказать несколько слов о том, как нынче пишутся Windows-программы. Большинство программистов-индивидуалов, работающих исключительно под Windows – «шареварщики», которые стремятся максимально нарастить «рыночную стоимость» своего продукта. В результате, вместо того, чтобы сделать простую утилиту для управления фотокамерой с помощью PTP и продавать ее, скажем, за пять единиц (и не надо говорить мне, что она стоит дороже, я написал такую на C# примерноза 2 часа, начиная с изучения PTP Windows API и заканчивая украшением пользовательского интерфейса), они объединяют свое приложение с каталогизатором фотографий и генератором Web-галерей и продают за 40 тех же единиц (это при том, что менеджер каталогов и генератор галерей и так есть практически в каждой графической утилите).
Знакомьтесь: gphoto2
Переходя на платформу Linux, мы оказываемся в несравненно более дружественной среде. Рабочая лошадка Linux для камер, поддерживающих PTP – консольная программа gphoto2 (а точнее – библиотека libgphoto2). Установите ее (желательно – самую последнюю версию; исходные тексты можно взять на http://www.gphoto.org или LXFDVD) и затем скомандуйте в окне консоли:
gphoto2 --list-cameras
Будет распечатан список фотокамер, которые поддерживает текущая версия gphoto2. Собираясь покупать «мыльницу» специально для экспериментов, прихватите с собой копию этого списка.
Убедитесь, что ваша камера находится в режиме PTP, подключите ее к компьютеру и скомандуйте:
gphoto2 -l
Эта команда выдаст список хранилищ данных для обнаруженного оборудования. Он может выглядеть, например, так:
There is 1 folder in folder ‘/’. - store_00010001 There are 2 folders in folder '/store_00010001'. - DCIM - MISC There is 1 folder in folder '/store_00010001/DCIM'. - 101NIKON There are 0 folders in folder '/store_00010001/DCIM/101NIKON'. There are 0 folders in folder '/store_00010001/MISC'.
Отлично, наша камера опознана.
Утилита gphoto2 таит в себе массу возможностей. Так, команда
gphoto2 --list-config
распечатывает список настроек, которыми можно управлять с помощью gphoto2. В моей системе он выглядит так:
/main/actions/autofocusdrive /main/actions/manualfocusdrive /main/settings/datetime /main/settings/fastfs /main/settings/capturetarget /main/imgsettings/imagequality /main/imgsettings/imagesize /main/capturesettings/autofocusmode /main/capturesettings/focallength /main/capturesettings/focusmode /main/capturesettings/flashmode /main/other/5001 /main/other/5003 /main/other/5004 /main/other/5008
Как видно, программа контролирует режимы автофокуса, вспышки, фокусного расстояния, размера и качества сохраняемого изображения, а также поддерживает несколько неведомых настроек типа main/other/5008. На самом деле они дублируют приведенные выше, но используют в описаниях названия на языке текущей локали (скажем, метка для /main/other/5003 в моей системе гласит: «Размер изображения», а для /main/imgsettings/imagesize – «Image Size»). Кстати, программа gphoto2 старается переводить сообщения фотокамеры на язык системы, независимо от того, на каком языке «говорит» само устройство. Теперь командуем:
gphoto2 --get-config=/main/imgsettings/imagesize
в результате получаем:
Type: RADIO Current: 3072x2304 Choice: 0 1024x768 Choice: 1 2048x1536 Choice: 2 2592x1944 Choice: 3 3072x2304
Из вывода ясно, что камера поддерживает четыре размера изображения, и выбран максимальный – 3072 × 2304. Заметьте, что в первой строке указан тип настройки – RADIO (что в данном случае означает «переключатель»), то есть допускается выбрать только одно из предложенных значений (этот параметр можно использовать при динамическом построении графической оболочки к утилите gphoto2). Уменьшим размер изображений:
gphoto2 --set-config=/main/imgsettings/imagesize=1024x768
Скомандовав еще раз
gphoto2 --get-config=/main/imgsettings/imagesize
вы можете убедиться, что значение параметра imagesize изменилось. Отметим, что новая настройка сохранится и после выключения фотоаппарата. Ну и, наконец, самое главное:
gphoto2 --capture-image
Эта команда заставляет камеру сделать снимок. После непродолжительной задержки «из камеры вылетит птичка», а результат будет сохранен на внутреннем диске (рис. 2). Команда
gphoto2 --capture-image-and-download
делает снимок и автоматически загружает изображение на компьютер.
Понятное дело, программа gphoto2 не была бы самой собой, если бы не обладала целым набором команд для перемещения файлов между фотоаппаратом и компьютером. Так, команда
gphoto2 --get-all-files --folder=/store_00010001/DCIM/101NIKON
скопирует все файлы изображений из папки фотоаппарата /store_00010001/DCIM/101NIKON в текущую директорию вашего компьютера.
К слову, gphoto2 – это не просто утилита командной строки, принимающая задания в виде аргументов. У нее есть еще и режим оболочки (рис. 3), запускаемый ключом --shell, который позволяет перемещаться по внутреннему диску фотокамеры как по локальной файловой системе. Еще один вариант «графического интерфейса», позволяющего выбирать настройки камеры, запускается ключом --config.
Раскол продолжается
Из листинга вы можете понять, фотоаппаратом какой фирмы я пользуюсь. Поклонникам Canon я могу напомнить анекдот про старообрядца, которому подарили фотоаппарат конкурирующей фирмы. Бородач растоптал его со словами: «Никогда в моем доме ничего никонианского не было и не будет!»
Ну и что из этого?
Так в чем же преимущество консольной утилиты gphoto2 перед красочными приложениями для Windows? Прежде всего, она делает именно то, что должна делать, и ничего более. Ее компактность позволяет объединять ее с другими программами тем способом, какой нужен пользователю. Консольную программу легко использовать в других приложениях, написанных на различных интерпретируемых (и не только) языках программирования.
Между прочим, у gphoto2 есть опция передачи полученных изображений в стандартный поток вывода. Тут уж возможности ограничены только вашей фантазией. Можно заставить камеру делать фотоснимки через указанные промежутки времени (первое, что приходит в голову). Стоит, правда, отметить, что захват снимков фотокамерой осуществляется с задержкой в несколько секунд (ее длительность зависит от модели камеры), так что делать фотографии слишком часто в автоматическом режиме не удастся. Можно, конечно, заставить камеру снимать кино (если она поддерживает эту возможность). Объединив gphoto2 с другими программами, можно генерировать фотоснимки в ответ на некие события: например, фотографировать каждого, кто входит в систему с местного терминала. А подключив фотоаппарат к нетбуку, вы сможете делать снимки не только там, куда никогда не ступала нога человека, но и там, куда его рука не дотянется.
Очень полезную возможность gphoto2 представляет ключ --hook-script, позволяющий привязать файл сценария оболочки к определенным событиям программы gphoto2. Допустим, надо, чтобы фотокамера делала фотоснимки в заданные моменты времени и загружала их на указанный ей FTP-сервер (попробуйте найти такую программу под Windows!). Начнем по порядку. Команда вызова gphoto2 в этом случае должна выглядеть так:
gphoto2 --capture-image-and-download --hook-script test-hook.sh
Если вы хотите получать снимки через регулярные интервалы времени, эту команду можно вызывать с помощью cron. Сценарий test-hook.sh – учебный пример, который демонстрирует взаимодействие сценариев оболочки и команды gphoto2 (вы найдете его в директории /usr/share/doc/gphoto2/). Ниже приводится текст этого сценария, модифицированный для наших целей:
#!/bin/sh self=`basename $0` case “$ACTION” in init) echo “$self: INIT” ;; start) echo “$self: START” ;; download) echo “$self: uploading $ARGUMENT” ./ftp-upload.sh $ARGUMENT rm $ARGUMENT ;; stop) echo “$self: STOP” ;; *) echo “$self: Unknown action: $ACTION” ;; esac exit 0
Сценарий узнает о событиях gphoto2 при помощи переменной окружения $ACTION. Событие init соответствует инициализации камеры, start указывает на начало выполнения камерой команды, событие download свидетельствует о том, что камера готова к передаче файла (его имя при этом содержится в переменной $ARGUMENT). Событие stop указывает на завершение операции. В нашем сценарии в ответ на событие download мы вызываем сценарий ftp-upload.sh, который загружает файл на заданный FTP-сайт. Вот текст этого сценария:
#!/bin/bash HOST=’ftp.foo.com’ USER=’user’ PASSWD='password' ftp -i -n $HOST << EOF user ${USER} ${PASSWD} binary put $1 quit EOF
Для программы gphoto2 существует несколько графических оболочек и вспомогательных утилит, но они предназначены в основном для управления сохраненными в фотокамере фотографиями и передачи их на компьютер. Программа gtkam использует gphoto2 для точного определения модели подключенной камеры (рис. 4) и управления сохраненными снимками (рис. 5).
Инструмент gphotofs позволяет подмонтировать файловую систему камеры к локальной файловой системе. Например, команда
gphotofs /home/andrei/nikon/
монтирует файловую систему камеры в директорию /home/andrei/nikon/, после чего содержимое диска камеры можно просматривать в любом файловом менеджере (рис. 6).
Кодируем с libgphoto2
Как уже отмечалось выше, возможности протокола PTP в планеперемещения файлов не дают ничего принципиально нового посравнению с USB Mass Storage, так что если вы заинтересовались PTP, рассмотренные утилиты вряд ли вас удовлетворят. Вы можете добавить функциональность управления камерой в свои программы, используя возможности консольного режима gphoto2 и языки сценариев (и для многих случаев этого будет вполне достаточно), но есть и другой путь. Утилита gphoto2 представляет собой, по сути, оболочку вокруг библиотеки libgphoto2, которая экспортирует интерфейс управления PTP-устройствами на языке С. Для демонстрации возможностей этого интерфейса мы напишем небольшую графическую программу Libgphoto Tester, используя библиотеку Qt. Вы найдете ее на диске в архиве libgphototester. Наша программа (рис. 7) умеет определять, подключена ли к системе PTP-камера, выводить подробную информацию о найденном устройстве и делать фотоснимок по команде пользователя.
После установки пакетов разработчика libgphoto2 у вас появится весьма внушительный набор заголовочных файлов в директории /usr/include/gphoto2. Все элементы API, относящиеся к управлению камерой, собраны в файле gphoto2‑camera.h. Начало и конец любой процедуры, работающей с PTP-устройством посредством libgphoto2, должны выглядеть примерно так:
GPContext * context; Camera * camera; int init_result; context = gp_context_new(); gp_camera_new(&camera); init_result = gp_camera_init(camera, context); /* Командуем фотокамерой */ ... gp_camera_exit(camera, context); gp_camera_free(camera); gp_context_unref(context);
Структура GPContext – это контекст API, в котором содержится служебная информация о текущей сессии libgphoto2. Большинство функций API получает как один из параметров указательна нее. Структура Camera представляет в программе фотокамеру (libgphoto может работать с несколькими камерами одновременно). Функция gp_camera_new() создает экземпляр структуры Camera, а gp_camera_init() инициализирует фотокамеру (тут и происходит первое обращение к физическим устройствам).
На самом деле эта функция делает гораздо больше, чем может показаться, исходя из ее названия. В системе всегда присутствует несколько USB-портов, к которым может быть подключено несколько PTP-устройств. Функция gp_camera_init() сканирует порты в поисках PTP-устройств и инициализирует первое найденное. Если вы хотите работать сразу с несколькими устройствами, вам лучше всего посмотреть исходный текст функции gp_camera_init() в файле /trunk/libgphoto2/libgphoto2/gphoto2‑camera.c из Subversion-репозитория libgphoto2. Дело в том, что интерфейс для работы с несколькими устройствами в libgphoto2 все еще не обрел стабильности, а документация в некоторых частях просто отсутствует. Самый лучший справочник в данном случае – исходный текст функции, которая гарантированно может обрабатывать несколько подключенных устройств.
Если фотокамера была инициализирована с помощью вызова gp_camera_init(), работу с ней следует завершить при помощи функции gp_camera_exit(). После этого структура Camera освобождается с помощью gp_camera_free(), а контекст – с помощью функции gp_context_unref().
Чтобы заставить фотокамеру сделать снимок, воспользуемся функцией gp_camera_capture(). Она возвращает информацию о сделанном снимке в структуре CameraFilePath. Члены path и name этой структуры содержат, соответственно, путь и имя файла в файловом пространстве фотокамеры.
Для работы с файлами, сохраненными на внутреннем диске камеры, а также для передачи их на компьютер, существует свой набор функций, объявленных в файле gphoto2‑file.h. Прежде всего, для работы с файлами нужно создать хотя бы один экземпляр структуры CameraFile, которая является аналогом дескриптора файла для файловых функций libgphoto2:
CameraFile * file; result = gp_file_new(&file); ... gp_file_free(file);
Функция gp_file_free() уничтожает соответствующий объект. Для работы с файлами вам также доступны функции gp_file_open(), gp_file_save(), gp_file_copy() и gp_file_detect_mime_type() (определение типа данных файла). Последняя из них будет полезна, если вы пишете свой собственный файловый браузер для фотокамеры (напомню, что современный фотоаппарат может хранить в себе не только фотографии, но и видеоролики и даже звуковые файлы сопровождения в различных форматах). Функция gp_file_append() осуществляет добавление данных в уже существующий файл, а функция gp_file_clean() (или, в зависимости от версии API, gp_file_delete()) очищает файлы.
Скачать файл из фотокамеры в компьютер можно, например, с помощью функции gp_file_get(), но при этом надо учитывать, что аргументом функции, представляющим файл-приемник для скачивания, должен быть указатель на структуру CameraFile. Функция gp_file_new_from_fd() позволяет связать структуру CameraFile и обычный идентификатор файла Linux (а если учесть, что идентификатор файла в Linux может представлять практически что угодно, начиная с устройства и заканчивая потоком ввода другой программы, возможности открываются необозримые).
И наконец
Теперь вы знаете достаточно для того, чтобы доработать программу Libgphoto tester и научить ее не только делать снимки, но и показывать результаты в режиме реального времени. Оставляю вам это в качестве домашнего задания.
Разумеется, наличие управляемой компьютером «мыльницы» (как, впрочем, и дорогой зеркальной фотокамеры) не сделает из вас Картье-Брессона. С другой стороны, новые технические возможности в сочетании со старой человеческой способностью к творчеству позволят вам реализовать такие идеи, которые даже в голову не приходили великим фотографам прошлого.�