BoothPi/Photobooth.py

344 lines
11 KiB
Python
Executable File

# 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/BoothPi/.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/BoothPi/.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 = False
camera.vflip = False
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('omxplayer 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/BoothPi/.images/' + str(int(time.time())))
GPIO.output(buttonled, 1) ## Turn on GPIO pin 7
# Restart the slideshow
slideshowRunning = True