Introduction: Raspberry Pi Photo Booth Controller
Photo booths are fun! They can inspire goofiness in just about anyone.
For my first project with the Raspberry Pi I built a photo booth for a party. This was a great project for learning to tinker with photography and electronics on the Pi. People were happy with the booth, and curious how it was built, so I thought I'd share what I learned.
This project tutorial assumes a very basic knowledge of linux/bash and the ability to solder a simple circuit.
Overview: four main components of the booth
- Camera, with USB connection and preferably with an AC power adapter and tripod
- Photo printer
- Controller, the user interface, with a start button and indicator lights, and a brain of Raspberry Pi, which controls the camera, assembles the photo montage, and drives the printer. This is what I will show you how to build.
- Booth enclosure, not strictly necessary, but does provide the intimacy essential for maximum fun; best when filled with beautiful women in fabulous dresses
Parts needed for the controller:
Enclosure
Raspberry Pi
Powered USB hub
Electronic components:
GPIO ribbon cable
Perma-proto-board Pi cobbler
LED-illuminated momentary contact switch
LED indicator lights
various resistors
wire for making connections
soldering iron and solder
During setup:
SD card reader
computer to set up the SD card
monitor/TV with HDMI
USB keyboard and mouse
Step 1: Setup RPi
Do you already have your RPi with Raspbian installed and can access it through SSH? Then skip to Step 2: Connect the Camera. Otherwise, grab your RPi, an SD card, an SD card reader, and another computer and:
1) Prepare an SD card with a Raspbian install
2) Boot up and configure
Enable the SSH server during configuration, so you can run your RPi headless, i.e., without a monitor or keyboard, via the command line from a remote terminal.
3) Set up a network connection
Open Midori to test if you are connected to the internet. Then, once you are successfully connected, open a terminal window and type "sudo ifconfig" to get your ethernet IP address; write down this number (something like 10.0.1.19).
4) and lastly, set up SSH
Log in to your RPi from another computer on the network. Now you're ready for the next step.
Step 2: Connect the Camera
After getting your Pi initially set up, get a camera hooked up. You can control most cameras with the RPi using Gphoto2, a well supported, actively updated, free, command-line digital camera controller for *NIX operating systems. Using scripts you can thus automate your camera's controls.
Install gphoto2 from the command line (via SSH on your other computer, or LXTerminal from the RPi desktop)
1) Update the system:
sudo apt-get update
2) Download and run this script, which installs and updates gphoto2:
sudo wget raw.github.com/gonzalo/gphoto2-updater/master/gphoto2-updater.sh
sudo chmod 755 gphoto2-updater.sh
sudo ./gphoto2-updater.sh
3) To ensure your camera mounts properly to be controlled via USB (see this thread), remove these files:
sudo rm /usr/share/dbus-1/services/org.gtk.Private.GPhoto2VolumeMonitor.service
sudo rm /usr/share/gvfs/mounts/gphoto2.mount
sudo rm /usr/share/gvfs/remote-volume-monitors/gphoto2.monitor
sudo rm /usr/lib/gvfs/gvfs-gphoto2-volume-monitor
4) Restart
sudo shutdown -r 0
5) Attach your camera to the RPi with USB and test it out
ls
gphoto2 --capture-image-and-download
ls
Do you see a new file in the home directory? This is the photo that was captured. Yay!
Step 3: Connect the Printer
Now you need a printer. A dye sublimation printer makes decent quality photo prints fairly quickly. I used the Canon Selphy CP900, which I randomly bought at Best Buy for this project without doing much research. Luckily it worked out.
Use CUPS to drive the printer. You can check to see if CUPS supports a particular printer. The Canon Selphy CP-900 is not on that list. I got it working using the SELPHY-CP770 driver (this was the lucky part), which, though it was available through the actual CUPS installation, I do not see on the list linked to above (as of Feb 2014).
1. Install CUPS from the RPi command line (for further guidance/troubleshooting, see here)
sudo apt-get install cups
Add the user (pi) to the group allowed to print (lpadmin)
sudo usermod -a -G lpadmin pi
2. Connect your printer and setup CUPS from the RPi desktop
Attach to the RPi by USB and power up your printer.
Open Midori and type into the URL line
http://127.0.0.1:631
This will open up the CUPS setup.
Click "administration" and "add printer;" enter your username and password (e.g., the defaults "pi" and "raspberry").
You should see your printer listed under "local printer;" select it and click "continue."
Set the name and location of your printer as you like, and click "continue."
Select the driver for your printer. For me, there was no CP900 driver, but the CP770 driver worked just fine.
Set the default options.
Now you should be done with printer setup.
3. Test printing
Check for active printers
lpstat -p
Do a test print. "lpstat -p" will give you the name of the printer, in my case "Canon_CP900," which was designated during the CUPS setup above. List the files in your home directory by typing "ls." "capt0000.jpg" is the photo previously captured by the camera. Substitute your own printer name and photo capture name into the command to print, "lp"; the -d argument determines the print destination.
lp -d Canon_CP900 capt0000.jpg
Step 4: Build the Electronics
There are three parts for the user interface:
- start button, lights up when ready for shooting and starts the photobooth process when pressed
- pose LED, tells the subjects to pose, flashes faster just before the shot
- please wait LED, lights up while the photos are being processed and sent to the printer, lets the next subjects know they need to wait; necessary so the print queue doesn't fill up and crash the Pi
To me the most exciting thing about the RPi is the GPIO (general purpose input/output), which lets you work with electronics with your Pi.
1) Set up the GPIO as described here.
2) Get the electronics. I used LEDs that came with the RPi starter pack. The lighted momentary pushbutton switch is also from Adafruit. Not very fancy but it all works just fine.
3) Wire the circuit. See the circuit diagram. After breadboarding it up and trying it out to your satisfaction, solder everything together using a PermaProto for Pi. I made the "pose" light a green LED and the "please wait" light a red LED. The "ready to start" LED in the diagram was wired to light the pushbutton switch.
4) Mount it all in a box. I ended up using a cheap enclosure from Radio Shack. I wish I had spent more time on this part of the project, making it look more fancy. I bet you can get more creative.
Almost ready to go! Now we just need to do a bit more prep of the RPi.
Note: the button is based on this useful tutorial.
Step 5: Set Up Full Rig, Download Scripts, Test
1) Connect the printer and camera to the RPi using a USB hub.
2) Make a label for the montage. Name the file "photobooth_label.jpg" and put it onto your RPi in the home directory.
I used Illustrator, exporting a ~110x1100 pixel .jpg, oriented vertically. The words read from bottom to top. I guess you could also use Photoshop, GIMP, or Inkscape.
Upload the photobooth label file to your RPi by opening a local terminal window, change to the local directory where this file is and transfer the file:
scp photobooth_label.jpg pi@10.0.1.19:~
Alternately you could email it to yourself and use the RPi GUI to get the file. Or, with a windows machine, use WinSCP.
3) Get the scripts. On the RPi make a directory for and download three scripts; make them executable.
mkdir -p ~/scripts/photobooth
cd ~/scripts/photobooth
sudo wget raw.github.com/safay/RPi_photobooth/master/assemble_and_print
sudo wget raw.github.com/safay/RPi_photobooth/master/photo_booth.py
sudo wget raw.github.com/safay/RPi_photobooth/master/startup_script
sudo chmod 755 *
Edit the "assemble_and_print" script. Change the "lp" line to include your printer name.
sudo nano assemble_and_print
^X to exit, save the changes
4) Make directories for assembling the montage and archiving shots.
cd ~
mkdir photobooth_images
mkdir PB_archive
5) Install ImageMagik
sudo apt-get install imagemagick
6) Test: try it out and run the script (ctrl-C to quit).
sudo python ~/scripts/photobooth/photo_booth.py
If it's glowing, push the button.
7) Set script to run automatically.
If the step above works, then make the script run automatically at startup. This will be allow the booth to operate without an external computer or network.
sudo nano /etc/rc.local
Now, add the line
/home/pi/scripts/photobooth/startup_script &
above the "exit 0" line
^X to exit, save the changes
Restart the RPi
sudo shutdown -r 0
The script should automatically run in the background.
You can get archived photomontages off the RPi by scp'ing from your local terminal:
scp pi@10.0.1.19:~/PB_archive/* .
Step 6: Have Fun!
To fully deploy the photo booth, you're going to need a party.
As for building an actual booth? Here's an opportunity for you to get crazy creative. You can hang some fabric in a corner. Or here's a good description of how to build one out of PVC: https://www.instructables.com/id/DIY-Portable-Wedding-Photo-Booth/step4/Frame/
Don't forget to supply props.
Please comment and let me know how it goes.
Be sure to have fun!
Thank you to Daniel B for inspiration and clueing me in to dye sublimation printers and ImageMagick code. And thank you to HK, TK, and MM for helping make the booth a total success.
18 People Made This Project!
- JasonH100 made it!
- darkman77 made it!
- MarkusA12 made it!
- sojojo made it!
- joolTiunda made it!
- aviatorbja made it!
- maewert made it!
- darkman77 made it!
- stehaa made it!
See 9 More
119 Comments
7 years ago on Introduction
If you want to use a Pentax DSLR these are not working with gphoto2, so i wrote a pentax version of safay's script. Could be downloaded from
https://github.com/thedarkman/RPi_photobooth/tree/...
9 years ago on Step 2
Be sure to check that gphoto2 supported camera page lists "image capture" for you camera, otherwise it won't work.
Reply 9 years ago on Introduction
Great point! Edited accordingly; thanks for the tip.
3 years ago on Step 6
Nice project, some remarks though:
1.: don't run wget as root. It's potentially dangerous, and if you don't do it, you don't need to run all the scripts as root. they're perfectly fine with running as user.
2.: if you do all the assemble and print stuff in python, you'll get a better feedback when stuff is done, at least the montage part.
5 years ago
hey the only selphy printer available to me is the canon selphy cp-1000 would this work for the project as usb direct printer or as a network printer.
Reply 3 years ago
Hi
did the Canon Selphy CP-1000 print correctly? Via USB?
thank you for answer
7 years ago
here is the python code. works great, though I have broken the camera module when a cat jumped on my setup and knocked it over.
#!/usr/bin/python
import RPi.GPIO as GPIO, sys, time, os, subprocess, pygame, picamera
# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
SWITCH = 24
GPIO.setup(SWITCH, GPIO.IN)
RESET = 25
GPIO.setup(RESET, GPIO.IN)
PRINT_LED = 22
POSE_LED = 18
PRINT_SWITCH=14
GPIO.setup(PRINT_SWITCH, GPIO.IN)
BUTTON_LED = 23
GPIO.setup(POSE_LED, GPIO.OUT)
GPIO.setup(BUTTON_LED, GPIO.OUT)
GPIO.setup(PRINT_LED, GPIO.OUT)
GPIO.output(BUTTON_LED, True)
GPIO.output(PRINT_LED, False)
# variables
poser=["First Pose","Number two","Third time","last Pose!"]
width = 1024
wide = 1024
wid2 = width/2
height = 768
high = 768
high2 = height/2
continue_loop = True
current_image = 0
camera = picamera.PiCamera()
camera.preview_alpha = 128
waitforit=200
counter=waitforit
dir="/home/pi/PB_archive/"
allpics=os.listdir(dir)
image_count=len(allpics)
for file in allpics:
print file
#pygame stuff
white = pygame.Color(255,255,255)
black = pygame.Color(0,0,0)
pygame.init()
pygame.display.init()
bigfont=pygame.font.SysFont("freeserif",300)
#screen = pygame.display.set_mode((width,height),pygame.FULLSCREEN)#FULLSCREEN
def GetDirectory(list):
#get directory contents for /home/pi/PB_archive/
list = os.listdir(dir)
for file in list:
print file
def BigNumber(number):
backgroundCenterSurface = pygame.Surface((width,height))
backgroundCenterSurface.fill(black)
screen.blit(backgroundCenterSurface,(0,0))
backgroundCenterSurface.set_alpha(25)
screen.blit(bigfont.render(number, 1, white),(200,0))
pygame.display.update()
def DrawCenterMessage(message,x,y,ss):
#displays notification messages onto the screen
ww = 0.4*ss*len(message)
hh = ss
xx = x-ww/2
yy = y-hh/2
backgroundCenterSurface = pygame.Surface((width,height))#size
backgroundCenterSurface.fill(black)
megafont = pygame.font.SysFont("freeserif",ss,bold=1)
screen.blit(backgroundCenterSurface,(0,0))#position
screen.blit(megafont.render(message, 1, white),(xx+10,yy+10))
pygame.display.update()
def DrawCenterMessage2(message,x,y,ss):
megafont = pygame.font.SysFont("freeserif",ss,bold=1)
letsurf = megafont.render(message, 1, white)
ww = letsurf.get_width()
hh = letsurf.get_height()
BGSurface = pygame.Surface((ww+10,hh+10))
BGSurface.fill(black)
BGSurface.blit(letsurf,(5,5))
screen.blit(BGSurface,(x-ww/2-5,y-hh/2-5))
pygame.display.update()
def terminate():
pygame.display.quit
pygame.quit()
sys.exit
# KRT 17/06/2012 rewrite event detection to deal with mouse use
def checkForKeyPress():
for event in pygame.event.get():
if event.type == QUIT: #event is quit
terminate()
elif event.type == KEYDOWN:
if event.key == K_ESCAPE: #event is escape key
terminate()
else:
return event.key #key found return with it
# no quit or key events in queue so return None
return None
DrawCenterMessage("Hit the switch",wid2,high2,100)
while True:
if (GPIO.input(SWITCH)):
snap = 0
while snap < 4:
DrawCenterMessage(poser[snap],wid2,high2+100,100)
GPIO.output(BUTTON_LED, False)
GPIO.output(POSE_LED, True)
time.sleep(1.5)
camera.start_preview()
for i in range(5):
GPIO.output(POSE_LED, False)
time.sleep(0.5)
GPIO.output(POSE_LED, True)
time.sleep(0.5)
countdown=str(5-i)
BigNumber(countdown)#,300,300,(wid2-150),(10))
GPIO.output(POSE_LED, False)
DrawCenterMessage("SNAP",wid2,high2,100)
fname = "/home/pi/photobooth_images/photobooth"+str(snap)+".jpg"
#command = "raspistill -t 1000 -o /home/pi/photobooth_images/photobooth"
# +str(snap) +".jpg -q 100 -w 1200"
camera.capture(fname)
camera.stop_preview()
freeze=pygame.image.load(fname)
freeze=pygame.transform.scale(freeze,(width,height))
screen.blit(freeze,(0,0))
pygame.display.update()
#os.system(command)
#print(command)
#print(gpout)
#if "ERROR" not in gpout:
snap += 1
GPIO.output(POSE_LED, False)
time.sleep(2)
DrawCenterMessage("Please Wait",wid2,high2,100)
GPIO.output(PRINT_LED, True)
# build image and send to printer
if (GPIO.input(14)==0):
DrawCenterMessage("saving picture",wid2,high2-2,100)
subprocess.call("sudo /home/pi/scripts/photobooth/assemble_and_save", shell=True)
else:
DrawCenterMessage("printing",wid2,high2,100)
subprocess.call("sudo /home/pi/scripts/photobooth/assemble_and_print", shell=True)
# TODO: implement a reboot button
#if event.type == QUIT:
# pygame.quit()
# sys.exit()
# Wait to ensure that print queue doesn't pile up
# TODO: check status of printer instead of using this arbitrary wait time
time.sleep(10)
DrawCenterMessage("Ready",wid2,high2,100)
GPIO.output(PRINT_LED, False)
GPIO.output(BUTTON_LED, True)
#update directory of image files
allpics=os.listdir(dir)
image_count = len(allpics)
#/home/pi/PB_archive/PB_${suffix}.jpg
else:
#switch not pressed
counter -= 1
time.sleep(.01)
if (GPIO.input(RESET) == 0):
terminate()
if (counter < 1):
counter=waitforit
image = pygame.Surface((width,height))
if (current_image<image_count):
fname=allpics[current_image]
#DrawCenterMessage(fname,400,70,100,350)
magna=pygame.image.load(dir+fname)
magna=pygame.transform.scale(magna,(width,height))
screen.blit(magna,(0,0))
pygame.display.update()
current_image += 1
if (current_image >= image_count):
current_image=0
Reply 4 years ago
Hi'
I'm a french photographer.
i'm trying your code, because i would like to print message on a photobooth's screen.
And your solution seem like i want.
But a message appear.
i wrote:
sudo python ~/scripts/photobooth/photo_booth.py
and raspbian wrote:
File "/home/pi/scripts/photobooth/photo_booth.py", line 131
print file
^
IndentationError: expected an indented block
Could you help me :)
7 years ago
This is a cool project. I did most of this, and it all tested fine. What I am having a problem with is the wiring. I tried following the schematic,, then your picture but i can't follow the wires in that pic, Do you have any others? So far every time i hit the button to take the pic it reboots my RPi.
In the top of the pic, are you wiring all of the Orange/Whites together? Then out to the LED?
Thanks for any help.
Dave
Reply 7 years ago
Glad you enjoy the project! Unfortunately I don't have the project any more, so I can't advise you about the orange and white wires other than to say that it's not safe to assume anything about the wire colors. Follow the schematic only.
As to why you're getting a reset when pushing a button, the only hardware reset I know of uses the P6 header:
http://elinux.org/RPi_Low-level_peripherals
So there's probably a problem with the software. I'd add some debugging code to the script to see exactly what is happening when you push the button.
Reply 7 years ago
Thanks for the quick reply and link. I meant to delete my comment this morning. I was able to actually get the electronics to work. Yay me!
However now I am stuck on getting it to print. All of tests worked fine. It takes the four pics but I get the folliowng error for printing:
sudo: /home/pi/scripts/photobooth/assemble_and_print: command not found.
Grrr. But that's what makes it fun and challenging.
Reply 4 years ago
Bonjour.
Moi aussi j'ai la réponse de python "sudo: / home / pi / scripts / photobooth / assemble_and_print: commande introuvable"
il y a-t-il une solution ?
Satané serpent ! #pyhton
Reply 7 years ago
Never mind, I mistakenly loaded the files into the main Pi directory. This has definitely giving me some experience with the Pi. I will post a pic once complete. I need it for my daughter's bday party this weekend.
4 years ago
Hope someone can help me!
I did everything as described but when i run the script, now LED glows and without pressing the button, it starts taking pictures. The rest work fine. I've Rebuilt the electrics with a breadboard and its the same. But when i disconnect the wire at the #24 the scrips waits... But now i've found out, that it doenst matter which wire touches #24, the script starts taking Pictures. Even if the wire is connected to nothing. Sorry for my bad englisch.
5 years ago
Hi, i am replicating this project for a fest in my college and i am wondering if the cannon selphy cp 1000 could be used for this project? as i am not able to find other printers in India. are drivers available for this and if so how can i use the cp 1000 if the drivers are not availalbe. can i use a windows pc and use the printer as a network printer>>> Thanks !!!
5 years ago
This is a great project, cant wait to start. Im just waiting for all the bits to be delivered. Ive already got a printer but i cant find it on CUPS, its a mitsubishi d80dw. What options do i have, can i get it working with out too much of an headache? Thanks
5 years ago
Hello !
Thanks for sharing !
Any idea how to replace the gphoto2 command line by a raspistill one to use the picam instead of an external camera ?
My main problem is to give a name to the photo which are taken so the assemble and print command can find the photos...?
Thank you !
5 years ago
Hello
Super tutorial. It works great.
Only one problem : the script didn't run automatically. I made exactly what do you said, but when I reboot, nothing. The green led didn't turn on, and when I push the button for the photo, nothing happening.
I made and remade the "7) Set script to run automatically.", but still nothing.
Somebody have an Idea of my problem ?
Thanks a lot
5 years ago
This is simple amazing project. I am in, i just waiting for arriving of photo printer MITSUBISHI CP 80DW. Does anybody try with this printer?
I have one concern: my photoboot will work 24/7.
When the script photobooth.py is in ready status (Ready for next job), CPU on my raspberry is on 50% (python while loop), is there any fix code for this?
7 years ago on Introduction
HI and thanks for a great tutorial! I have a Makey Makey laying around at home so I was hoping to skip GPIO all togethe instead making the script/Gphoto listen for a keystroke, is that even possible?