Raspberry Pi DSLR Photo Booth

This is a photobooth built for a wedding. It was designed with the following requirements in mind

  1. Take very good photos
  2. Run entirely off battery power
  3. Be easy to use such that it can run unattended
  4. Allow users to immediately download their photos onto their phone
  5. Be easy to set up and take down
  6. GUI needs to be backwards-compatible enough to run on my 1st gen iPad Mini (released in 2012!)

iPad User Interface

Technical Details

The hardware is quite simple, consisting of only the following:

The software stack is as follows

Making photos available via QR download code

We first capture the image:

# (in the controller's `create` method)
@photo = Photo.new
GPhoto2::Camera.first do |camera|
	file = camera.capture
	file.save('tmp/image.jpg')
	@photo.image.attach(io: File.open('tmp/image.jpg'), filename: 'image.jpg')
end
			

Then, when the user requests a QR code for that image:

# (in the controller)
def qr_image
# get the raw file for the image attached to the 'photo' image (in a given quality variation [decent])
image = @photo.image.variant(:decent).processed.download

begin
  # attach that file to the 'cloud_image' entity of the model.
  # This uploads the file to the cloud storage service (e.g. S3)
  @photo.cloud_image.attach(io: StringIO.new(image), filename: 'image.jpg')
rescue Seahorse::Client::NetworkingError
  # if it fails, show the user an error image
  send_file("app/assets/images/no-net.png", type: 'image/png', disposition: 'inline') and return
end 
@photo.save!
# get a pre-signed URL for the cloud image and present it as a QR code. 
# the URL is only valid for 10min, as per config/environments/production:
# config.active_storage.service_urls_expire_in = 10.minutes
qr = RQRCode::QRCode.new(@photo.cloud_image.url, level: :l).as_png(size: 460)
send_data qr, type: 'image/png', disposition: 'inline'
end
			

The view loads the QR code as an image from the above controller method:

<%= image_tag("#{photo_path(@photo)}/qr_image?cache_buster=#{Time.now.to_time.to_i}", 
	style: 'width: 500px; height: 500px; border: none; margin: 0; background: url(' + asset_path('Loading_icon.gif') + ') no-repeat center;') 
%>
			

I think Rails does a great job here -- many other frameworks would need many more lines for such a task.

System calls

The Rails application makes a number of system calls to make sure the OS is in a fit state to run the photobooth: