Журнал LinuxFormat - перейти на главную

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$ACTIONin 
 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 и научить ее не только делать снимки, но и показывать результаты в режиме реального времени. Оставляю вам это в качестве домашнего задания.

Разумеется, наличие управляемой компьютером «мыльницы» (как, впрочем, и дорогой зеркальной фотокамеры) не сделает из вас Картье-Брессона. С другой стороны, новые технические возможности в сочетании со старой человеческой способностью к творчеству позволят вам реализовать такие идеи, которые даже в голову не приходили великим фотографам прошлого.�

Персональные инструменты
купить
подписаться
Яндекс.Метрика