# Raspberry Pi - Photo Booth # # Copyright (c) 2014, John Croucher - www.jcroucher.com # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, this # list of conditions and the following disclaimer in the documentation and/or other # materials provided with the distribution. # # 3. Neither the name of the copyright holder nor the names of its contributors may # be used to endorse or promote products derived from this software without specific # prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGE. import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) import tweepy import time from threading import Thread from subprocess import call from datetime import datetime import picamera import PIL from PIL import Image #import cups import os import sys import pygame import random import requests import urllib buttonled = 7 flashled = 22 button = 18 slideshowRunning = True basewidth = 177 # Used for merging the photos onto one printPhoto = False TweetPhoto = True Combine = True imgPath = '/home/pi/.images/tmp' # Light big light GPIO.setup(buttonled, GPIO.OUT) ## Setup GPIO Pin 7 to OUT GPIO.output(buttonled, 1) ## Turn on GPIO pin 7 # Push button for starting the photo sequence GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Display surface pygame.init() pygame.mouse.set_visible(0) w = pygame.display.Info().current_w h = pygame.display.Info().current_h screenSize = (w, h) screen = pygame.display.set_mode(screenSize, pygame.FULLSCREEN) # Full screen the display with no window # Used for loading a random photo for the slideshow def random_file(dir): files = [os.path.join(path, filename) for path, dirs, files in os.walk(dir) for filename in files] return random.choice(files) def displayImage(file): screen.fill((0,0,0)) img = pygame.image.load(file) img = pygame.transform.scale(img,(w,h)) # Make the image full screen screen.blit(img,(0,0)) pygame.display.flip() # update the display # Display a random image def slideshow(): while True: if slideshowRunning == True: checkEvents() randomFile = random_file('/home/pi/.images') displayImage(randomFile) time.sleep(10) # pause # Handle events like keypress def checkEvents(): for event in pygame.event.get(): # Shutdown the application if quit event or escape key is pressed if event.type == pygame.QUIT or ( event.type is pygame.KEYDOWN and event.key == pygame.K_ESCAPE ): slideshowRunning = False pygame.quit() sys.exit() if event.type is pygame.KEYDOWN and event.key == pygame.K_f: # Switch the display mode between full screen and windowed if screen.get_flags() & pygame.FULLSCREEN: pygame.display.set_mode(screenSize) else: pygame.display.set_mode(screenSize,pygame.FULLSCREEN) # On screen text message def displayStatus(status): screen.fill((0,0,0)) font = pygame.font.SysFont("monospace",92) text = font.render(status,True,(255,255,255)) # Display in the center of the screen textrect = text.get_rect() textrect.centerx = screen.get_rect().centerx textrect.centery = screen.get_rect().centery screen.blit(text,textrect) pygame.display.flip() # update the display # Merge all photos onto one ready for printing def combineImages(): if Combine == True: displayStatus('Saving') # Do the merging blankImage = Image.open('blank.jpg') image1 = Image.open(imgPath + '/image1.jpg') image1 = image1.resize((640,480)) blankImage.paste(image1, (0,0)) displayStatus('25%') image2 = Image.open(imgPath + '/image2.jpg') image2 = image2.resize((640,480)) blankImage.paste(image2, (0,480)) displayStatus('50%') image3 = Image.open(imgPath + '/image3.jpg') image3 = image3.resize((640,480)) blankImage.paste(image3, (640,0)) displayStatus('75%') image4 = Image.open(imgPath + '/image4.jpg') image4 = image4.resize((640,600)) blankImage.paste(image4, (640,480)) displayStatus('100%') blankImage.save(imgPath + '/combined.jpg', 'JPEG', quality=80) displayStatus('Saved') # Check net def CheckNet(): try : stri = "https://www.google.com" data = urllib.urlopen(stri) Tweet() except: displayStatus('Offline') time.sleep(3) # pause # Upload to Twitter def Tweet(): if Combine == True: if TweetPhoto == True: displayStatus('Tweeting') # Consumer keys and access tokens, used for OAuth consumer_key = 'DVW3lqng3wY6hE77L7HV3Pq6o' consumer_secret = 'o8hOsaAGuDkoHyH8CjBrhhAYidf8KsyubAVhad6bAZDlP0nQ6U' access_token = '2867471873-HPqS3vtqHUOJHnWskkZK4ofZNWM7laef6L1LTWa' access_token_secret = 'rZbxlDLqlgGuHZRXSH2V2rMRzWJLAIXWSbxorpZrFgVDX' # OAuth process, using the keys and tokens auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) # Creation of the actual interface, using authentication api = tweepy.API(auth) # Send the tweet with photo photo_path = imgPath + '/combined.jpg' status = 'Photo Tweet from HudgellBooth: ' + i.strftime('%Y/%m/%d %H:%M:%S') api.update_with_media(photo_path, status=status) displayStatus('Complete') if Combine == False: if TweetPhoto == True: displayStatus('Tweeting') # Consumer keys and access tokens, used for OAuth consumer_key = 'DVW3lqng3wY6hE77L7HV3Pq6o' consumer_secret = 'o8hOsaAGuDkoHyH8CjBrhhAYidf8KsyubAVhad6bAZDlP0nQ6U' access_token = '2867471873-HPqS3vtqHUOJHnWskkZK4ofZNWM7laef6L1LTWa' access_token_secret = 'rZbxlDLqlgGuHZRXSH2V2rMRzWJLAIXWSbxorpZrFgVDX' # OAuth process, using the keys and tokens auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) # Creation of the actual interface, using authentication api = tweepy.API(auth) # Send the tweet with photo 1 displayStatus('25%') photo_path = imgPath + '/image1.jpg' status = 'Photo Tweet from HudgellBooth: ' + i.strftime('%Y/%m/%d %H:%M:%S') api.update_with_media(photo_path, status=status) # Send the tweet with photo 2 displayStatus('50%') photo_path = imgPath + '/image2.jpg' status = 'Photo Tweet from HudgellBooth: ' + i.strftime('%Y/%m/%d %H:%M:%S') api.update_with_media(photo_path, status=status) # Send the tweet with photo 3 displayStatus('75%') photo_path = imgPath + '/image3.jpg' status = 'Photo Tweet from HudgellBooth: ' + i.strftime('%Y/%m/%d %H:%M:%S') api.update_with_media(photo_path, status=status) # Send the tweet with photo 4 displayStatus('100%') photo_path = imgPath + '/image4.jpg' status = 'Photo Tweet from HudgellBooth: ' + i.strftime('%Y/%m/%d %H:%M:%S') api.update_with_media(photo_path, status=status) displayStatus('Complete') # Print the photo def printPhoto(): if printPhoto == True: displayStatus('Printing') conn = cups.Connection() printers = conn.getPrinters() printer_name = printers.keys()[0] conn.printFile(printer_name, imgPath + '/combined.jpg',"TITLE",{}) time.sleep(2) # Combine Preview def combinePre(): if Combine == True: displayImage( imgPath + '/combined.jpg' ) # Display a preview of the combined image # Thread for the slideshow t = Thread(target=slideshow) t.start() with picamera.PiCamera() as camera: while True: checkEvents() # Needed to check for keypresses and close signals # Putton press to start the photo sequence input_state = GPIO.input(button) if input_state == False: GPIO.output(buttonled, 0) ## Turn off GPIO pin 7 # Stop the slideshow slideshowRunning = False displayStatus('') # Start the camera preview camera.hflip = True camera.start_preview() # Make the destination path for the photos if not os.path.exists(imgPath): os.mkdir(imgPath) # Loop through the 4 photo taking sequences GPIO.setup(flashled, GPIO.OUT) ## Setup GPIO Pin 22 to OUT GPIO.output(flashled, 1) ## Turn on GPIO pin 22 i = datetime.now() #take time and date for filename now = i.strftime('%Y%m%d-%H%M%S') for pNum in range (1,5): camera.annotate_text = 'Photo ' + str(pNum) + ' of 4' time.sleep(1) for countDown in range (3,0,-1): camera.annotate_text = str(countDown) time.sleep(1) camera.annotate_text = '' #camera.resolution = (2560, 1920) camera.resolution = (1280, 960) os.system('mpg321 CSC.mp3 &') camera.capture ( imgPath + '/image' + str(pNum) + '.jpg') time.sleep(3) # Stop the camera preview so we can return to the pygame surface GPIO.output(flashled, 0) ## Turn on GPIO pin 7 camera.stop_preview() combineImages() CheckNet() printPhoto() combinePre() time.sleep(5) # Move the temp files to a new dir based on the current timestamp so they can be retrieved later os.rename(imgPath, '/home/pi/.images/' + str(int(time.time()))) GPIO.output(buttonled, 1) ## Turn on GPIO pin 7 # Restart the slideshow slideshowRunning = True