I'm pretty new to Python and raspberry Pi, having mostly a background in shell scripting.

My goal is to have have a Pi set up, with the preview continuously running, waiting for a user to press 'Space Bar' at which point it takes a photo, shows it (overlay) and returns to the preview.

So far I have got the preview up, the image capture (Still working out how to avoid the stutter), and then I am overlaying the result for a bit.

But I'm stuck on how to capture a users keypress, take the photo, and continue on with the preview. Nothing I have seen online gives a very clear example of how to capture user input. I have gotten the sys.stidn code up and running in a separate script, but I can't seem to get the looping to work the way I want it to; Take photo, return back to preview state.

I feel like this should be easier, but somehow I just can't seem to get it. Any help would be great.

import picamera
import Image
from time import sleep
import datetime as dt
import itertools
import tty, sys

with picamera.PiCamera() as camera:
        camera.framerate = 15
        camera.vflip = True
        camera.hflip = True
        #camera.brightness = 70
        #camera.sharpness = 10
        #camera.saturation = 100
        camera.resolution = (1296, 972)
        #print ( Time_String )
        camera.annotate_text = 'Cheese Dude!'

        while 1:
                ch = sys.stdin.read(1)
                if ch == ' ':
                elif ch == 'q':

        def capture():
                Time_String = dt.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
                ImageName = './photos/image' + Time_String + '.jpg'
                #will now try and overlay the captured image on the preview for a short period, to show how it looked
                # Create an image padded to the required size with
                # mode 'RGB'
                img = Image.open(ImageName)
                pad = Image.new('RGB', (
                        ((img.size[0] + 31) // 32) * 32,
                        ((img.size[1] + 15) // 16) * 16,
                # Paste the original image into the padded one
                pad.paste(img, (0, 0))
                o = camera.add_overlay(pad.tostring(), size=img.size)
                o.alpha = 255
                o.layer = 3

        def exitCam():
  • Don't you just need to add a while loop just before the camera.start_preview()?
    – joan
    Aug 17 '15 at 10:23

I've seen Pygame game development library being successfully used in similar scenarios before, handling realtime systems and machinery in production, not just toy examples. I think it's a suitable candidate here too. Check out [pygame.key][2] module for what is possible to do with the keyboard input.

In short, if you are not familiar with game development, you basically continuously poll for events such as input state changes inside an 'infinite' game loop and react accordingly. Usually update the parameters of the system using deltas per time elapsed. There's plenty of tutorials on that and Pygame available around and Pygame docs are pretty solid.

A simple example of how to go about it:

import pygame


# to spam the pygame.KEYDOWN event every 100ms while key being pressed
pygame.key.set_repeat(100, 100)

while 1:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_w:
                print 'go forward'
            if event.key == pygame.K_s:
                print 'go backward'
        if event.type == pygame.KEYUP:
            print 'stop'

You'll need to play with pygame.KEYDOWN, pygame.KEYUP and pygame.key.set_repeat depending on your needs.


you should get information from input devices like keyboard and touch screens , there is a tool named evdev you should first install evdev with this code, than you can monitor the input devices.

$ sudo pip install evdev

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.