view · edit · print · history

There are two ways digital cameras interface with PCs.

The first case is that the camera represents itself as a USB mass storage class device. Getting content off those cameras is similar to getting content from a memory stick. Just mount them as a fat filesystem and copy the content.

The other breed of cameras (e.g. Canon) uses PTP (picture transfer protocol). In order to use this a program like gphoto2 needs to be used. This page only covers PTP cameras.

Use gphoto to read images off a supported USB-connected digital camera, and back them up to a USB hard drive. A list of supported cameras is on the gphoto site.

I do this with my OpenDebianSlug device.

It was as simple as installing the hotplug and gphoto2 packages and then writing a shell script which does a gphoto2 --get-all-files and then moves the files based upon the date stored in the exif data to the appropriate directory. I just added a call to run that script to the end of /etc/hotplug/usb/libgphoto2.

So all you do it plug the camera into the free USB port and turn it on in view mode (and wait a while if you took lots of photos). You then have to delete the images from the camera manually, since I'm too paranoid to do that in the script.

--- Sam Holden

What would be interesting is to use libmagick to create a fake photo inside the camera acknowledging the pictures have downloaded correctly, so you can erase them by hand without fear.

--- Pablo Duboue

SlugOS/BE 4.8 Beta (NSLU2) with PTP cameras

The SlugOS/BE 4.8 doesn't use hotplug but triggering events on detection of the USB camera can be done via /etc/udev/rules.d/ rules files. This enables running of a simple gphoto2 --get-all-files script.

A summary of the steps is as follows
1. Find udev information for given camera.
2. Create new /etc/udev/rules.d/10-local.rules to run a script when your device is detected

Firstly, to find udev information for your camera install the udev-utils package

#ipkg install udev-utils

Now plug in the USB plug and turn on the camera and make sure it has been identified by the USB system

#dmesg | tail -n 10

This should show that a high speed device USB device is using ehci_hcd and address X

Where X will be a number (1,2,3, etc) that we use to find udev information about the device

#udevinfo -a -p /sys/class/usb_devices/usbdev1.X/dev

(note: I believe /usbdev1.X maybe /usbdev2.X depending on the USB port the camera is plugged into)

Now some of the device details from udevinfo output are used to create a udev rule that uniquely identifies the camera.

For an excellent explanation of udev rules see http://www.reactivated.net/writing_udev_rules.html(approve sites) by Daniel Drake.

For my Canon 40D, using some of the outputs from udevinfo I created the following udev rule and added it to a new file /etc/udev/rules.d/10-local.rules

SUBSYSTEM=="usb_device", SUBSYSTEMS=="usb", ATTRS{idProduct}=="3146", ATTRS{idVendor}=="04a9", MODE="0666", SYMLINK+="cannon_40d", RUN+="/usr/scripts/canon_40d.sh"

On detection of the USB camera by udev, this rule uniquely identifies the camera using the idProduct and idVendor numbers, it then sets the access mode to 0666 (read and write access for everyone), it also creates a symbolic link /dev/canon_40d (note, this dev can not be used for much as the device uses PTP). Finally the rule runs my script located at /usr/scripts/canon_40d.sh

To reload this new udev rule run

#udevcontrol reload_rules

Now turn off and then turn back on the camera for it to be picked up by the new udev rule (or run #udevtrigger)

My very simple canon_40d.sh script is the following

# Called from /ect/udev/rules.d/10-local.rules
/bin/beep -f 392.0 -n -f 493.9
/usr/scripts/get_photos.sh &

(note 'beep' just beeps the on-board buzzer to let you know the camera has been detected, if you want to make the buzzer accessible by normal users edit the /etc/udev/rules.d/permissions.rule and add the following rule
KERNEL=="event[0-9]*", ATTRS{name}=="ixp4xx beeper", MODE="0666"
This sets the access mode of the beeper to 0666)

The actual getting of the photos from the camera is not done here, but rather I call another of my simple scripts get_photos.sh. This is because udev is blocked until returned from the canon_40d.sh script.

This script simply copies all the photos into a 'pre_sort' folder, I then use another script to sort the photos based on the exif data (using a native compile of exif).

# Downloads all photos from attached camera
# then beeps...
cd /home/nas/photos/pre_sort
gphoto2 --quiet -P
chmod -R 0755 /home/nas/photos/pre_sort
beep -r 3
/usr/scripts/sort_photos.sh &

And that it!

--- Alex Scott

udev rule for my cardreader:

BUS=="usb", KERNEL=="sd*", SYSFS{product}=="USB Reader", NAME(all_partitions)="%k", SYMLINK+="card_cf%n", \
 RUN+="/etc/udev/scripts/cp_pictures.sh %k cf", OPTIONS+="all_partitions"
BUS=="usb", KERNEL=="sd*", SYSFS{product}=="USB Reader", NAME(all_partitions)="%k", SYMLINK+="card_mmc%n", \
 RUN+="/etc/udev/scripts/cp_pictures.sh %k mmc", OPTIONS+="all_partitions"
BUS=="usb", KERNEL=="sd*", SYSFS{product}=="USB Reader", NAME(all_partitions)="%k", SYMLINK+="card_ms%n", \
 RUN+="/etc/udev/scripts/cp_pictures.sh %k ms", OPTIONS+="all_partitions"
BUS=="usb", KERNEL=="sd*", SYSFS{product}=="USB Reader", NAME(all_partitions)="%k", SYMLINK+="card_sd%n", \
 RUN+="/etc/udev/scripts/cp_pictures.sh %k sd", OPTIONS+="all_partitions"

And the script cp_pictures.sh i use for downloading from my cardreader which holds the media of a Canon 300D:

if [ -z $cf ]; then 

today='uploaded_'$(date +%F)

ext=("*.crw" "*.thm" "*.jpg")

lockfile -r0 -30 $lockfile
if [ "$?" -ge "1" ]; then 
 exit 1

mount -s -t auto $cf $cfdev
stat $cfdev/dcim/*canon &> /dev/null
if [ "$?" -ge "1" ]; then
 rm -f $lockfile
 umount $cf -lf
 exit 1

logger udev.info "cp_pictures.sh called with $1 and $2"
count=$(ls $cfdev/dcim/*canon/* | grep "" | wc --lines)

if [ "$count" = "0" ]; then
 umount $cf -lf
 rm -f $lockfile
 exit 1

logger udev.info "cp_pictures.sh: $cf, $2, cp $count photos to $fotos"
mkdir $fotos
for e in $( echo ${ext[
} ); do
 for i in $( find $cfdev/dcim/*canon/$e ); do
  echo "copying: $i"
  cp -Puf $file $fotos
  if [ "$?" = "1" ]; then 
   echo "file: $i copy error"
   echo "$i copied."
   rm $i


chmod 770 $fotos -R chown samba:sambausers $fotos -R

files=$(ls $cfdev/dcim/*canon/* | grep "" | wc --lines) if [ "$files" = "0" ]; then

 echo removing directories...
 rm -rf $cfdev/dcim/*canon
 umount $cf -lf
 rm -f $lockfile


 echo more files than expected, exiting.
 rm -f $lockfile
 exit 1


/etc/nslu2/melody_disk_on.sh /etc/nslu2/leds_off.sh exit 0


It expects 2 parameters: the device and a name for a lockfile which prevents the script from being started twice. It then mounts the device, creates a folder with the actual date, copies files one by one and umounts the device. It additionallz plays a melody after successfull recognition and umount (these scripts use the leds command).


view · edit · print · history · Last edited by Alex Scott.
Based on work by de, Alex Scott, PabloDu, Steffen, eFfeM, tman, Sam Holden, rwhitby, and kc.
Originally by kc.
Page last modified on May 13, 2008, at 10:00 AM