gphoto-webui — A PHP Web UI for gphoto2

The reason I wrote this was simple: I wanted a remote control for my DSLR. That way, I can snap photos while I was in front of the camera from my smartphone and review them after the fact. I’m somewhat of a shutter bug in addition to being a tech geek. I could have bought a fancy dongle and installed an app on my phone to get the same sort of behavior, but I already had a Raspberry Pi (RasPi), and thought, “What if I could use that little mini computer to control my DSLR, then use my phone as remote?” Something like this maybe?

[Smartphone] ~~~WiFi~~~ [RasPI] >—USB—< [Camera]

Turns out, I can thanks to a project called gphoto. gphoto is a CLI tool for doing things on many different models of cameras from all kinds of manufacturers, including Canon, which I have. All it needed was a way to control gphoto from my smartphone. I could use an SSH shell or a remote desktop, but where’s the fun in that? I applied some PHP, HTML, and JavaScript magic to make it all happen so any device with a web browser can control the camera as a remote control. I simply wrote a web based front-end for gphoto that is mobile friendly and posted it to GitHub for all to use, modify, and enjoy.

I’m using a RasPi model “B” (512 MB), but there’s no reason this wouldn’t work on model “A” or another box using Debian or Ubuntu Linux. I also have a WiFi adapter on my RasPi. Mobile WiFi might be challenge… You could “tether” your RasPi to your phone or tablet, or your could set up your RasPi as a WiFi AP too. My phone and tablet both support tethering, so I just use that.

Also, the RasPi needs power, and it doesn’t have a battery. It requires a 5v 1000ma DC connection to work. This isn’t to hard to reproduce with off the shelf batteries and a little McGyvering. There’s also after-market battery packs for the RasPi too.

Anyways, here’s how to make it work…

  1. Power up your Raspberry Pi. Pull up a Terminal, logon through SSH, or whatever you do to get to a console.
  2. Update your Raspberry Pi
    sudo apt-get update
    sudo apt-get upgrade
  3. Install the following packages.
    sudo apt-get install imagemagick php5 php5-cli php5-imagick gphoto2 zip unzip exiv2

    Note: You do not need a web server. In fact, I wouldn’t recommend it for this little app because this app will need more elevated permissions than the www-data user has. Configuring the server to run a user with elevated permissions might work, but not necessary. PHP has a built in development server that will work just fine and also run as the logged on user.

    DON’T RUN THIS ON THE PUBLIC INTERNET. THIS IS NOT INTENDED FOR THAT, NOR IS IT SECURE!

    Note: As of writing this, the gphoto2 package that comes with Raspian is a little outdated (version 2.4). I had some problems with my camera (a Canon 50D) and the packaged version, so I compiled it from the source. Here’s a cut-and-paste recipe for doing just that. I’d recommend running sudo -i before performing this guide to ensure no problems with permissions. This isn’t necessary if 2.4 will work with your camera. Try the apt package first before doing this…

    http://whysohardtoget.blogspot.com/2013/05/compiling-gphoto2-252-with-raspberry-pi.html

  4. Download the gphoto web ui from from github. (wget works if you’re using a console.) You’ll need to be in a writeable folder. I suggest your home folder.
    cd ~
    wget https://github.com/theonemule/gphoto-webui/archive/master.zip
    
  5. Extract the files into a directory
    unzip master.zip
  6. In the console, cd to that directory
    cd gphoto-webui-master
  7. Start the php server. This will bind the server to port 8000 on all IP’s.
    php5 -S 0.0.0.0:8000
  8. Point your browser to http://x.x.x.x:8000/index.html x.x.x.x is the IP of your Raspberry Pi.
  9. The WebUI is pretty much self explanatory. Hit the aperture icon to take a picture. View the images on the Gallery page. The images are captured in whatever format the camera is set to use, and this does support RAW images as well. Images are stored on the Raspberry Pi’s SD card, not in the camera’s memory.
  10. The source images can be downloaded through the Web UI or can be FTP’d through an app like FileZilla over SFTP. The images are all stored in the “images” folder in relative to the root of the application. (i.e. ~/gphoto-webui-master/images) .

Raspi to Camera appui2   Main Screen

34 comments on “gphoto-webui — A PHP Web UI for gphoto2Add yours →

  1. Hi, any chance that you’ll add a timelapse feature? Gphoto2 has the -I and -F parameter for that. That would be really awesome! Take Care Torsten

  2. Thanks very much for taking the time to doc this, it’s been really helpful so far.

    I can’t quite get it to work perfectly though and wondered if you had any thoughts –

    I can take the photo from the web interface perfectly, but no images make it to the gallery. On the Pi screen I get
    Deleting ‘capt0000.jpg’ from folder ‘/’ …
    [date] IP [200]:/service.php?action=takePicture
    sh: 1: exiv2: not found
    [date] IP [200]:/service.php?action=getImages

    Any insight would be gratefully received 🙂

  3. Great project. Just stuck at getting the images to show on the Gallery page. They are in the images folder. On the selecting gallery.html the script calls getCamera
    then I get sh:1: exiv2: not found
    then calls getImages and then getCamera.

    Not that experienced so any help appreciated

    1. Sorry I haven’t replied yet… I haven’t got any notifications of new emails and have been moving as of late. I’ll look into this as soon as I get some free time.

    2. The script attempts to extract the JPEG thumbnail from the RAW image on the camera. What model of camera are you using?

      1. I get the same error, I am using a Nikon D700. Takes images just fine but nothing on the gallery page. I have shot in RAW and JPG formats. It does not convert the RAW (which is an NEF format), but the exception should catch the JPG and resize it.

        Thank you.

        1. The script attempts to extract a JPEG preview from the RAW photo, because converting the RAW images to jpeg was CPU intense for the RasPi. I took this attempt at first, but it was unusable.

  4. I just found out you need to install exiv2 with sudo apt-get exiv2 install

    Not I notice it is not building the thumbnail so if you make a directory under the images folder called thumbs, the whole thing works.

  5. Hi,
    Same problem as John:
    [Wed Apr 1 22:52:38 2015] 192.168.4.64:51630 [200]: /service.php?action=getImages
    sh: 1: exiv2: not found.
    My camera is a Canon PowerShot A620 (PTP mode).
    Any idea?
    Rgds

  6. All, I forgot to include a package on the apt-get install list…

    sudo apt-get install exiv2

    Run this command it should fix the problem.

    blaize

  7. Just got your WebUI up and running today. Had a little issue with my Nikon D7000 but upgrading to the latest version of gphoto2 fixed that. Have you given any more thought to adding a time lapse feature? Currently I run a separate script for that but it would be awesome if it were incorporated into your WebUI.

    Thanks,
    Matt

  8. First of all thanks for taking the time to write this up! I wrote a photo app in python a while back and wanted to be able to have a gui for people to interact with and this is exactly what I needed. I, too, had to upgrade to the latest gphoto2 to get things working. For anyone else having issues, I used this post (https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=70049). I also added a battery status to the page since I will be using this as a photobooth and want a quick way to let me/people know how much battery is left. If anyone is interested its on github (https://github.com/goteamtim/gphoto-webui). I will also be porting my time lapse feature from my python code into this project for anyone interested. Thanks again, awesome code!

    –Tim

  9. Hello,

    Thank’s god I found your documentation on how to trigger a digital camera from a web php application.
    I have a website and I want to control my canon camera from my web application based on PHP.

    Do you think this is possible ?

    Thank you in advance

    Tay

    1. Possible, yes… it’s largely depends on your camera though. I only used a small portion of what gphoto can do. All I’m doing is wrapping the gphoto cli executable with PHP code. You can see how I’m doing in the code and then add the parameters you want to the gphoto cli to add more finegrained control over the camera.

  10. *** Error ***
    Error capturing image
    ERROR: Could not capture image.
    ERROR: Could not capture.
    *** Error (-114: ‘OS error in camera communication’) ***

    [Wed Jan 27 14:56:46 2016] 192.168.0.18:54788 [200]: /service.php?action=takePicture
    [Wed Jan 27 14:56:46 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:56:46 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:56:46 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:56:46 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:56:46 2016] 192.168.0.18:54795 [200]: /service.php?action=getImages
    Detected a ‘Canon:EOS 20D (normal mode)’.
    Downloading ‘_MG_0753.CR2’ from folder ‘/DCIM/607CANON’…
    Deleting ‘_MG_0753.CR2’ from folder ‘/DCIM/607CANON’…
    [Wed Jan 27 14:57:30 2016] 192.168.0.18:54812 [200]: /service.php?action=takePicture
    [Wed Jan 27 14:57:36 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    Error: Directory (Last IFD item) with 16896 entries considered invalid; not read.
    Error: Directory (Last IFD item) with 16896 entries considered invalid; not read.
    [Wed Jan 27 14:57:37 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:57:37 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:57:37 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:57:37 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:57:37 2016] 192.168.0.18:54814 [200]: /service.php?action=getImages
    [Wed Jan 27 14:57:37 2016] 192.168.0.18:54815 [200]: /images/thumbs/capture-20160127-112854-001.CR2.jpg
    [Wed Jan 27 14:58:11 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:58:11 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:58:11 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:58:11 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:58:11 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 80
    [Wed Jan 27 14:58:11 2016] 192.168.0.18:54819 [200]: /service.php?action=getImages
    [Wed Jan 27 14:58:24 2016] 192.168.0.18:54820 [200]: /
    [Wed Jan 27 14:58:25 2016] 192.168.0.18:54821 [200]: /css/jquery.mobile-1.4.2.css
    [Wed Jan 27 14:58:25 2016] 192.168.0.18:54822 [200]: /js/jquery.js
    [Wed Jan 27 14:58:25 2016] 192.168.0.18:54823 [200]: /js/jquery.mobile-1.4.2.js
    [Wed Jan 27 14:58:25 2016] 192.168.0.18:54824 [200]: /js/controller.js
    [Wed Jan 27 14:58:26 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 54
    [Wed Jan 27 14:58:26 2016] 192.168.0.18:54825 [200]: /service.php?action=getCamera
    [Wed Jan 27 14:58:26 2016] 192.168.0.18:54826 [200]: /aperture.png
    [Wed Jan 27 14:58:26 2016] 192.168.0.18:54827 [200]: /css/images/ajax-loader.gif
    [Wed Jan 27 14:58:26 2016] PHP Warning: Creating default object from empty value in /home/pi/gphoto-webui-master/service.php on line 54
    [Wed Jan 27 14:58:26 2016] 192.168.0.18:54828 [200]: /service.php?action=getCamera
    [Wed Jan 27 14:58:26 2016] 192.168.0.18:45144 [404]: /favicon.ico – No such file or directory
    [Wed Jan 27 14:58:26 2016] 192.168.0.18:58952 [404]: /favicon.ico – No such file or directory
    Detected a ‘Canon:EOS 20D (normal mode)’.

    I copied some errors above that I am experiencing. Now the first image captures perfectly. However when capturing the second image it gives me the Detected a ‘Canon:EOS 20D (normal mode)’. and hangs there for about 5 mins after which it will again work perfect for one image and then do the samething again. I wish I understood php better so that I could better work through the problem however I’ve ran into my limits. Would you be able to provide some insight? BTW i was trying to run this on a raspberry pi. I was trying to get this going for my daughters birthday party however it seems to have the better of me at the moment. Thanks for share as its a great starting point.

  11. I also had to add a period to line 74 in front of ‘jpg’ to et rid of other errors I was experiencing.

    $im->writeImage(‘images/thumbs/’.$path_parts[‘basename’].’.jpg’);

    1. Sorry you’re experiencing difficulty. From the looks of it, this is something going on with gphoto trying to capture and image from the camera while the camera is still transferring the image to the computer. The transfer process can take a minute depending on the size of the image and the speed of the bus on the camera. Unfortunately, there’s not much I can do to offer you in terms of help on the camera itself. I wrote this for my 50d, which is the only model I’ve ever tested it with.

  12. Ok thank you for taking the time to respond. I’ll try with a newer camera to see if that improves the speed sufficiently.

  13. I used the newer 760d and there was no issues. Thank you for making a piece of technology available. Like others I’m looking to add-on to what you have started. If I manage to get anything interesting is there a way to update your source? How would you prefer to handle adding features?

    1. Fork it on github, or I can make you a developer on the project too. Whatever works for you.

      This is FOSS, so by all means, do.

      Blaize

  14. Gphoto2 detects the four cameras with auto detect. We select the first port by –port usb:xxx,yyy. The photos get dowloaded. We select the second port –port usb:xxx,zzz. The photos downloaded are the same which were loaded for port yyy. This is connected to raspberry two ports. Can you explain how to solve this. Thanks.

    1. Sorry you’re having trouble with it. This sounds like a problem with gphoto2, and I’m not the developer of this package. I really have only ever used gphoto with one camera. You could probably go over to the guys at gphoto and ask them why this is the case.

      http://gphoto.sourceforge.net/

  15. Hi,
    Is there any way you could suggest to also implement a live preview window in there? so you can see what you’re taking a picture of before you actually take it?
    I tried to implement this using –capture-movie for 4 days now but still can’t get it working properly. Ideally you would have a video stream server on RPi I guess, which you could then access from your browser on other computers.

    1. I like the idea, but truth is I don’t know of a clean way to do that… The love video would need to the streamed through another means. gphoto is designed for capturing video rather than streaming it.

      If the camera does an RTSP stream or something like that, this might be possible. I use RTSP for other utilities apps, but unfortunately not this one.

  16. Hello,

    would it be possible to add the timelapse feature in the near future? I love your program, it works great with my Raspberry Pi 1 and my Nikon D3300. Thanks!

    1. You could use a cron job to do this.

      Run the php dev sever as a daemon

      nohup php -S 0.0.0.0:9000 > phpd.log 2>&1 &

      Then set a cron tab to call the web services that clicks the shutter using wget or something like that.

      */5 * * * * wget http://localhost:9000/service.php?action=takePicture 2>&1 &

      This will take a new photo every 5 minutes or so. You can log on to the UI and view them just like as if you were using the app.

Leave a Reply

Your email address will not be published. Required fields are marked *

five − 3 =