first commit
15
.pip/pip.log
Normal file
@ -0,0 +1,15 @@
|
||||
------------------------------------------------------------
|
||||
/usr/bin/pip run on Sat Nov 8 14:03:54 2014
|
||||
Cannot uninstall requirement pil, not installed
|
||||
|
||||
Exception information:
|
||||
Traceback (most recent call last):
|
||||
File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 104, in main
|
||||
status = self.run(options, args)
|
||||
File "/usr/lib/python2.7/dist-packages/pip/commands/uninstall.py", line 41, in run
|
||||
requirement_set.uninstall(auto_confirm=options.yes)
|
||||
File "/usr/lib/python2.7/dist-packages/pip/req.py", line 862, in uninstall
|
||||
req.uninstall(auto_confirm=auto_confirm)
|
||||
File "/usr/lib/python2.7/dist-packages/pip/req.py", line 410, in uninstall
|
||||
raise UninstallationError("Cannot uninstall requirement %s, not installed" % (self.name,))
|
||||
UninstallationError: Cannot uninstall requirement pil, not installed
|
22
.profile
Normal file
@ -0,0 +1,22 @@
|
||||
# ~/.profile: executed by the command interpreter for login shells.
|
||||
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
|
||||
# exists.
|
||||
# see /usr/share/doc/bash/examples/startup-files for examples.
|
||||
# the files are located in the bash-doc package.
|
||||
|
||||
# the default umask is set in /etc/profile; for setting the umask
|
||||
# for ssh logins, install and configure the libpam-umask package.
|
||||
#umask 022
|
||||
|
||||
# if running bash
|
||||
if [ -n "$BASH_VERSION" ]; then
|
||||
# include .bashrc if it exists
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
. "$HOME/.bashrc"
|
||||
fi
|
||||
fi
|
||||
|
||||
# set PATH so it includes user's private bin if it exists
|
||||
if [ -d "$HOME/bin" ] ; then
|
||||
PATH="$HOME/bin:$PATH"
|
||||
fi
|
BIN
OrignalImages/1415458989/combined.jpg
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
OrignalImages/1415458989/image1.jpg
Normal file
After Width: | Height: | Size: 194 KiB |
BIN
OrignalImages/1415458989/image2.jpg
Normal file
After Width: | Height: | Size: 194 KiB |
BIN
OrignalImages/1415458989/image3.jpg
Normal file
After Width: | Height: | Size: 195 KiB |
BIN
OrignalImages/1415458989/image4.jpg
Normal file
After Width: | Height: | Size: 194 KiB |
341
Photobooth.py
Normal file
@ -0,0 +1,341 @@
|
||||
# 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
|
||||
|
8
autostart.sh
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
# launcher.sh
|
||||
# navigate to home directory, then to this directory, then execute python script, then back home
|
||||
|
||||
cd /
|
||||
cd home/pi
|
||||
sudo python Photobooth.py
|
||||
cd /
|
BIN
blank_boarder.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
blank_noboard.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
ocr_pi.png
Normal file
After Width: | Height: | Size: 5.6 KiB |