├── .gitignore ├── MakingOf.jpg ├── PhotoBooth.jpg ├── curcuit-diagram.ai ├── curcuit-diagram.png ├── PhotoBooth.conf ├── LICENSE ├── README.md └── PhotoBooth.py /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | -------------------------------------------------------------------------------- /MakingOf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriskbx/raspi-photo-booth/HEAD/MakingOf.jpg -------------------------------------------------------------------------------- /PhotoBooth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriskbx/raspi-photo-booth/HEAD/PhotoBooth.jpg -------------------------------------------------------------------------------- /curcuit-diagram.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriskbx/raspi-photo-booth/HEAD/curcuit-diagram.ai -------------------------------------------------------------------------------- /curcuit-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kriskbx/raspi-photo-booth/HEAD/curcuit-diagram.png -------------------------------------------------------------------------------- /PhotoBooth.conf: -------------------------------------------------------------------------------- 1 | [program:photo-booth] 2 | command=python /home/pi/PhotoBooth/PhotoBooth.py 3 | autostart=true 4 | autorestart=true 5 | user=root -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 kris 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # raspi-photo-booth 2 | 3 | > Selfmade thermal printing photobooth featuring raspberry power. <3 4 | 5 | ![](./PhotoBooth.jpg) 6 | 7 | ### Hardware used 8 | 9 | * 1x [Raspberry PI Model B+](http://amzn.to/2eb9ngF) 10 | * 1x [Raspberry Camera NoIR V2](http://amzn.to/2eb7lx4) 11 | * 1x [Adafruit 60mm Arcade LED Button](http://amzn.to/2dHWpHU) 12 | * 1x [POS58 Thermal Printer](http://amzn.to/2d4lyea) 13 | * 1x [PNP transistor S8550](http://amzn.to/2edacW9) 14 | * 2x [220Ω resistor](http://amzn.to/2dJReXZ) 15 | * 1c [Buzzer 5V (active)](http://amzn.to/2dVzRS1) 16 | 17 | ### Getting started 18 | 19 | ``` 20 | # Clone the repository 21 | git clone https://github.com/kriskbx/raspi-photo-booth 22 | cd raspi-photo-booth 23 | 24 | # Install supervisor 25 | sudo apt-get install supervisord 26 | 27 | # Install python requirements 28 | pip install pillow picamera escpos RPi.GPIO 29 | 30 | # Add and edit the supervisor-conf to match your paths 31 | cp PhotoBooth.conf /etc/supervisor/conf.d/ 32 | vim /etc/supervisor/conf.d/PhotoBooth.conf 33 | 34 | # Edit the script to match your GPIO pins and your printer 35 | vim PhotoBooth.py 36 | 37 | # Update and start supervisor 38 | sudo supervisorctl reread 39 | sudo supervisorctl update 40 | sudo supervisorctl start photo-booth 41 | ``` 42 | 43 | ### Curcuit diagram 44 | 45 | ![](./curcuit-diagram.png) 46 | 47 | ### Making of 48 | 49 | ![](./MakingOf.jpg) 50 | 51 | ### Contributors 52 | 53 | Handwriting by [@johnnieparkstudio](https://www.instagram.com/johnnieparkstudio/) 54 | 55 | ### License 56 | 57 | MIT -------------------------------------------------------------------------------- /PhotoBooth.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import Image, time, os, picamera, sys, escpos.printer as printer, RPi.GPIO as GPIO 3 | 4 | # Vars 5 | LedPin = 11 6 | ButtonPin = 12 7 | BeepPin = 13 8 | Working = 0 9 | BeepTime = 0.2 10 | DisableBeep = False 11 | BasePath = os.path.dirname(os.path.realpath(__file__)) 12 | ImageDirectory = 'images' 13 | ImagePath = BasePath + '/' + ImageDirectory + '/' 14 | 15 | # Hardware 16 | def flashOn(): 17 | ledOn() 18 | beepOn() 19 | time.sleep(1) 20 | beepOff() 21 | 22 | def flashOff(): 23 | ledOff() 24 | 25 | def countdown(): 26 | for i in range(1, 5): 27 | ledOn() 28 | beepOn() 29 | time.sleep(BeepTime) 30 | ledOff() 31 | beepOff() 32 | time.sleep(1-BeepTime) 33 | 34 | def resizePhoto(photo): 35 | thumbnail = photo.replace('.jpg', '.thumbnail.jpg') 36 | try: 37 | im = Image.open(photo) 38 | im.thumbnail((380, 500), Image.ANTIALIAS) 39 | im.save(thumbnail, "JPEG") 40 | return thumbnail 41 | except IOError: 42 | print "cannot create thumbnail for '%s'" % photo 43 | return False 44 | 45 | def printPhoto(image): 46 | Thermal = printer.File("/dev/usb/lp0") 47 | Thermal.image(image) 48 | Thermal.control('LF') 49 | Thermal.control('LF') 50 | Thermal.control('LF') 51 | Thermal.control('LF') 52 | Thermal.control('LF') 53 | Thermal.close() 54 | 55 | def takePhoto(): 56 | image = ImagePath + str(time.time()) + '.jpg' 57 | print image 58 | Camera = picamera.PiCamera() 59 | Camera.resolution = (3280, 2464) 60 | Camera.capture(image) 61 | Camera.close() 62 | return image 63 | 64 | def beepOn(): 65 | global DisableBeep 66 | if DisableBeep == False: 67 | GPIO.output(BeepPin, GPIO.LOW) 68 | 69 | def beepOff(): 70 | GPIO.output(BeepPin, GPIO.HIGH) 71 | 72 | def ledOn(): 73 | GPIO.output(LedPin, GPIO.LOW) 74 | 75 | def ledOff(): 76 | GPIO.output(LedPin, GPIO.HIGH) 77 | 78 | # Event Listener 79 | def buttonPress(ev=None): 80 | global Working 81 | 82 | if Working == 0: 83 | Working = 1 84 | 85 | countdown() 86 | flashOn() 87 | 88 | image = resizePhoto(takePhoto()) 89 | if image != False: 90 | printPhoto(image) 91 | 92 | flashOff() 93 | 94 | Working = 0 95 | pass 96 | 97 | # Setup 98 | def setup(): 99 | if os.path.isdir(ImagePath) == False: 100 | os.mkdir(ImagePath, 0777) 101 | 102 | try: 103 | GPIO.cleanup() 104 | finally: 105 | pass 106 | 107 | GPIO.setmode(GPIO.BOARD) 108 | GPIO.setup(BeepPin, GPIO.OUT) 109 | GPIO.setup(LedPin, GPIO.OUT) 110 | GPIO.setup(ButtonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) 111 | 112 | ledOn() 113 | beepOn() 114 | time.sleep(0.1) 115 | ledOff() 116 | beepOff() 117 | 118 | # Loop, wait for button press 119 | def loop(): 120 | GPIO.add_event_detect(ButtonPin, GPIO.FALLING, callback=buttonPress) 121 | while True: 122 | pass 123 | 124 | # When running directly, make sure to cleanup GPIO 125 | def destroy(): 126 | ledOff() 127 | beepOff() 128 | GPIO.cleanup() 129 | 130 | if __name__ == '__main__': 131 | setup() 132 | try: 133 | loop() 134 | except Exception: 135 | destroy() --------------------------------------------------------------------------------