Camera to Drupal, instant image distribution
Abstract
This posts describes a method to take a picture with a digital camera (preferably a DSLR) and have it instantly uploaded to a Drupal website where it will be imported as an image node. All these steps will be done automatically and you will only need to press the shutter button of your camera for the whole process to start. Continuous shutting is also supported.
Camera to Drupal workflow: Trigger the whole process only by clicking the shutter of your camera.
Preparations
You will need to setup some tools in order to have all the software necessary for make this work.
-
Gphoto2
Gphoto2 is the command line utility that we will use for connecting the computer to the camera. It supports tethered capture, which is how the process of taking a picture and having it instantly downloaded to your computer is called. Other well known applications like Aperture and Lighroom support tethering but they are not command line scriptable, not opensource and too bloated for what we intend to do here.
Most used linux distributions have packages for installing gphoto2 including all its dependencies. In Mac you can install it using Macports with the command "sudo port install gphoto2". -
Drupal and Image module
A Drupal site with the image module will be needed. You must enable at least the image and image_import modules. They are easy to install and configure. I leave it as an exercise to the reader setup them for image importing from a folder.
Capturing images with Gphoto2
Some previous tips that will save you troubleshooting time:
-
Use the most recent version of gphoto2, the software has pretty active development with new camera drivers and bugfixes added frequently. I wasn't able to write this post until a recent version of gphoto fixed a bug with my camera.
-
If your computer has any software that automatically launches when you connect your camera it will need to be disabled or finished since it will prevent gphoto from communicating with the camera. There may even be some daemon process that launches in the background and prevents gphoto from working.
-
For example, Mac users will have to kill the process called PTPCamera or it will prevent gphoto from communicating with the camera. The PTPCamera process launches in the background each time you connect your camera to the computer. You can see if the process is running using the "ps ax | grep PTPCamera" command in a terminal. To kill this process you need to execute the command "killall PTPCamera". Do this every time you connect the camera in order to gphoto to work.
-
Disable the camera auto-off feature. Usually cameras have this energy saving feature preconfigured to something like 30 seconds. I recommend to turn this feature off when capturing images from the computer since the camera will turn off if you don't do anything in the configured time and you will have to turn it on again or reconnect it, kill the PTPCamera process (or equivalent), and launch gphoto again. Having this feature disabled will allow you to take pictures without interruptions as long as you (or you batteries) want.
Once you connect the camera to the computer and turn it on you can check if gphoto detects it with:
$ gphoto2 --auto-detect
Model Port
----------------------------------------------------------
Canon EOS 450D (PTP mode) usb:
Canon EOS 450D (PTP mode) usb:036,003
If you dont see your camera listed you should review the previous tips mentioned above. To see whether your camera is supported by gphoto2 you can use:
$ gphoto2 --list-cameras
Number of supported cameras: 1245
Supported cameras:
"Achiever Digital Adc65"
"AEG Snap 300"
"Agfa ePhoto 1280"
[...]
A long list of supported camera models will show. (grep is your friend).
Gphoto has several commands that you can test:
- gphoto2 --capture-image
Will capture an image an leave it in the memory card on the camera. - gphoto2 --capture-image-and-download
Will capture an image and download it immediately to the current folder
But the most interesting command is:
- gphoto --wait-event-and-download
renamed in recent versions to:
- gphoto2 --capture-tethered
This command waits for you to take a picture by pressing the shutter button on the camera and then the image is automatically downloaded to the current folder. The command keeps waiting for more events (more pictures) until you interrupt it with CTRL-C (you can also pass the amount of time to wait as an argument).
Uploading the pictures to the server
The gphoto option that makes the magic here is --hook-script. This options allows to specify an script that will be executed after the image has been downloaded and will receive the file name as an argument.
So if you do something like this:
$ gphoto2 --capture-tethered --hook-script=test-hook.sh
gphoto will wait for you to take pictures with the camera and after each picture is downloaded to the computer it will execute the test-hook.sh script passing the filename as an argument.
There is a stub test-hook.sh script in gphoto documentation folder (ie: /usr/share/doc/gphoto2). We will copy this stub script to the current folder and modify it to make it upload the picture to the server where our Drupal site is installed. Actually the file must be uploaded to the folder where the image_import module is configured to take the images from (config at admin/settings/image/image_import).
Depending on how you wish to upload the files to the server the commands to include in the script will be different. I will use SCP with public key authentication to upload the files. You may opt for FTP using wget, curl or ncftpput.
The final test-hook.sh script will look like this:
#!/bin/sh
self=`basename $0`
case "$ACTION" in
init)
echo "$self: INIT"
# exit 1 # non-null exit to make gphoto2 call fail
;;
start)
echo "$self: START"
;;
download)
echo "$self: DOWNLOAD to $ARGUMENT"
# Upload the image file to the server
DEST = example.com:/var/www/images.example.com/files/tmp/image/
scp $ARGUMENT $dest
# Call the image importing script
wget -O - -q \
"http://images.example.com/image-cap.php?filename=$ARGUMENT"
;;
stop)
echo "$self: STOP"
;;
*)
echo "$self: Unknown action: $ACTION"
;;
esac
exit 0
Importing the uploaded images
I will explain now the wget part of the previous script, this is the most tricky part of the whole process.
When you upload the files to your server you need some way to tell the Drupal site: "hey, I've uploaded these files, import them to nodes". You can do this from the user interface of the "image_import" module but we want to make it automatic so we need another way.
The simplest way to do this is to write a php script that will invoke the image module function for importing images. The script will look something like this:
<?php
require_once './includes/bootstrap.inc';
6">drupal_bootstrap(6">DRUPAL_BOOTSTRAP_FULL);
$filepath = 'sites/images.example.com/files/tmp/image/'. $_GET['filename'];
global $user;
# Impersonate user with 'create images' permission
$uid = 3;
$user = 6">user_load($uid);
if (!empty($filepath) && file_exists($filepath)) {
if ($node = image_create_node_from($filepath)) {
echo "NODE: $node->nid : $node->title : CREATED\n";
}
}
?>
The $uid variable must be set to the uid of a user with the 'create images' permission.
The $filepath variable assignment must also be modified to point to the directory where the images were uploaded.
You can also pass other arguments to the image_create_node_from function, like the taxonomy term of the gallery where you want the pictures archived (see image.module).
Save this script in the Drupal installation root directory (where index.php is). I named it image-cap.php but you should use another name so no one except you knows how to execute it.
And this is where the wget part of the test-hook.sh script comes in:
wget -O - -q \
"http://images.example.com/image-cap.php?filename=$ARGUMENT"
The command just calls the image-cap.php script in your server and pass the filename of the image that was just uploaded. The image-cap.php scripts will take this file and convert it to an image node.
Launching the whole process
Once you have configured everything as explained above, you should be able to launch:
$ gphoto2 --capture-tethered --hook-script=test-hook.sh
and each time you press the shutter button of your camera a picture will be taken, downloaded to the computer, uploaded to the server and imported into the Drupal site as an image node.
Gphoto works nicely queueing several pictures so you can take as many pictures or use continuous shooting without having to wait for the process to finish to take another picture, they will be nicely processed in sequence.
The output should look something like this:
$ gphoto2 --capture-tethered --force-overwrite --hook-script=test-hook.sh
test-hook.sh: INIT
test-hook.sh: START
Waiting for events from camera. Press Ctrl-C to abort.
Saving file as capt0000.jpg
test-hook.sh: DOWNLOAD to capt0000.jpg
capt0000.jpg 100% 544KB 543.8KB/s 00:00
NODE: 141 : capt0000.jpg : CREATED
Deleting 'capt0000.jpg' from folder '/'...
TIP: You may be insterested in setting the resolution of your camera to a low value since publishing pictures for the web doesn't require a high resolution and it will take more time to upload them which is bad if you want instant publishing.
Conclusion
Sport events, conference session or keynote live blogging, you name it... There are several situations in which instant publishing of your pictures may be insteresting and have a competitive advantage if you are a professional.
With the method described here you can achieve instant distribution of your pictures by using only opensource software.
The proccess can be adapted to other CMS choices and expanded for more extensive processing of images (watermarking, rotation) or further distribution of the created media.