diff --git a/README.md b/README.md index c6b3ca4..2fb3c1f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The following is required for running this photobooth application. I used the ve * [Pillow](http://pillow.readthedocs.org) (2.8.1) * [gPhoto](http://gphoto.sourceforge.net/) (2.5.6 or later) or [OpenCV](http://opencv.org) * Optional: [RPi.GPIO](https://pypi.python.org/pypi/RPi.GPIO) (0.5.11) -* Optional: [Piggyphoto](https://github.com/alexdu/piggyphoto) +* Optional: [gphoto2-cffi](https://github.com/jbaiter/gphoto2-cffi) or [Piggyphoto](https://github.com/alexdu/piggyphoto) RPi.GPIO is necessary to use external buttons as a trigger but it works just fine without. Triggering is then only possible using touch screen / mouse or key 'c'. @@ -115,7 +115,23 @@ A brief description on how to set-up a Raspberry Pi to use this photobooth softw ``` and run `photobooth.py` -8. Optional but highly recommended, as it improves performance significantly: Download the gPhoto2 Python-bindings [Piggyphoto](https://github.com/alexdu/piggyphoto) and put the folder `piggyphoto` into the Photobooth-directory. +8. Optional but highly recommended, as it improves performance significantly: install some Python bindings for gPhoto2. For that, either [Piggyphoto](https://github.com/alexdu/piggyphoto) or [gphoto2-cffi](https://github.com/jbaiter/gphoto2-cffi) can be used. At the moment, Piggyphoto doesn't allow to disable the sensor while idle, so gphoto2-cffi is preferred. + + 8.1 Installing gphoto2-cffi: + Install [cffi](https://bitbucket.org/cffi/cffi) + ``` + sudo apt-get install libffi6 libffi-dev python-cffi + ``` + Download and install gphoto2-cffi for gPhoto2 + ``` + git clone https://github.com/jbaiter/gphoto2-cffi.git + cd gphoto2-cffi + python setup.py build + sudo python setup.py install + ``` + + 8.2 Install Piggyphoto: + Download [Piggyphoto](https://github.com/alexdu/piggyphoto) and put the folder `piggyphoto` into the Photobooth-directory. 9. Optionally make the software run automatically on startup. To do that, you must simply add a corresponding line in the autostart file of LXDE, which can be found at `~/.config/lxsession/LXDE-pi/autostart`. Assuming you cloned the Photobooth repository into `/home/pi/photobooth`, add the following line into the autostart-file: ``` diff --git a/camera.py b/camera.py index c448570..3e79296 100644 --- a/camera.py +++ b/camera.py @@ -3,19 +3,33 @@ import subprocess +cv_enabled = False +gphoto2cffi_enabled = False +piggyphoto_enabled = False + try: import cv2 as cv cv_enabled = True print('OpenCV available') except ImportError: - cv_enabled = False + pass try: - import piggyphoto - piggyphoto_enabled = True - print('Piggyphoto available') + import gphoto2cffi as gp + gpExcept = gp.errors.GPhoto2Error + gphoto2cffi_enabled = True + print('Gphoto2cffi available') except ImportError: - piggyphoto_enabled = False + pass + +if not gphoto2cffi_enabled: + try: + import piggyphoto as gp + gpExcept = gp.libgphoto2error + piggyphoto_enabled = True + print('Piggyphoto available') + except ImportError: + pass class CameraException(Exception): """Custom exception class to handle camera class errors""" @@ -45,6 +59,9 @@ class Camera_cv: else: raise CameraException("OpenCV not available!") + def set_idle(self): + pass + class Camera_gPhoto: """Camera class providing functionality to take pictures using gPhoto 2""" @@ -53,14 +70,16 @@ class Camera_gPhoto: self.picture_size = picture_size # Print the capabilities of the connected camera try: - if piggyphoto_enabled: - self.cap = piggyphoto.camera() + if gphoto2cffi_enabled: + self.cap = gp.Camera() + elif piggyphoto_enabled: + self.cap = gp.camera() print(self.cap.abilities) else: print(self.call_gphoto("-a", "/dev/null")) except CameraException as e: print('Warning: Listing camera capabilities failed (' + e.message + ')') - except piggyphoto.libgphoto2error as e: + except gpExcept as e: print('Warning: Listing camera capabilities failed (' + e.message + ')') def call_gphoto(self, action, filename): @@ -82,17 +101,33 @@ class Camera_gPhoto: return output def has_preview(self): - return piggyphoto_enabled + return gphoto2cffi_enabled or piggyphoto_enabled def take_preview(self, filename="/tmp/preview.jpg"): - if piggyphoto_enabled: + if gphoto2cffi_enabled: + self._save_picture(filename, self.cap.get_preview()) + elif piggyphoto_enabled: self.cap.capture_preview(filename) else: raise CameraException("No preview supported!") def take_picture(self, filename="/tmp/picture.jpg"): - if piggyphoto_enabled: + if gphoto2cffi_enabled: + self._save_picture(filename, self.cap.capture()) + elif piggyphoto_enabled: self.cap.capture_image(filename) else: self.call_gphoto("--capture-image-and-download", filename) return filename + + def _save_picture(self, filename, data): + f = open(filename, 'wb') + f.write(data) + f.close() + + def set_idle(self): + if gphoto2cffi_enabled: + self.cap._get_config()['actions']['viewfinder'].set(False) + elif piggyphoto_enabled: + # This doesn't work... + self.cap.config.main.actions.viewfinder.value = 0 diff --git a/photobooth.py b/photobooth.py index b74baec..5d55bca 100755 --- a/photobooth.py +++ b/photobooth.py @@ -139,6 +139,7 @@ class Photobooth: self.gpio.set_output(self.lamp_channel, 1) while True: + self.camera.set_idle() # Display default message self.display.clear() self.display.show_message("Hit the button!")