2

I'm working on a project that requires me to have a viewfinder (barcode scanner).

I'm doing this with the Raspberry Pi Camera Module by the picamera python module, and I've got the whole detection and whatnot programmed.

Now I need to figure out how to display the preview from the Pi's Camera Module in a PyGame movie module. (If there's a better way to display video from an IO Stream in PyGame, please let me know.)

The reason I need to display it in PyGame is because I'll need to overlay controls on top of the video and be able to get input from a touchscreen I'm going to use as the viewfinder/screen for the Pi/project.

As far as I can see from the pygame.movie documentation, pygame.movie only loads from a file. Is there a way that I could convert the stream into a file-like object and have PyGame play from that?

Basically put, I need a way to take the io.BytesIO stream created in this example code, and display it in PyGame.

RPiAwesomeness
  • 5,009
  • 10
  • 34
  • 52
  • Have you seen the [camera tutorial on Adafruit](https://learn.adafruit.com/diy-wifi-raspberry-pi-touch-cam/overview)? That seems to have a live preview with buttons on top and uses a touchscreen. – elParaguayo Jan 07 '15 at 16:56
  • @elParaguayo Yes, I've seen that and do plan on taking some queues from it - I was just curious if anyone had had any experience in this on the site. – RPiAwesomeness Jan 07 '15 at 17:39
  • shoot...any update on this? I was kind of wanting to know how it was done too. Im trying to do the same thing although without a touch screen – Chaz May 22 '15 at 15:39

2 Answers2

4

If I understand excatly , you need to instant and infinite preview from camera module to your screen.

there is a way that I figure it out. first you must install Official V4L2 driver.

sudo modprobe bcm2835-v4l2

reference https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=62364

and than you should create a python file to compile and code this

import sys
import pygame
import pygame.camera

pygame.init()
pygame.camera.init()

screen = pygame.display.set_mode((640,480),0)
cam_list = pygame.camera.list_cameras()
cam = pygame.camera.Camera(cam_list[0],(32,24))
cam.start()

while True:
   image1 = cam.get_image()
   image1 = pygame.transform.scale(image1,(640,480))
   screen.blit(image1,(0,0))
   pygame.display.update()

   for event in pygame.event.get():
          if event.type == pygame.QUIT:
          cam.stop()
          pygame.quit()
          sys.exit()

this code from http://blog.danielkerris.com/?p=225 , in this blog they did with a webcam. you define your camera module as a webcam with v4l2 driver

also you should check this tutorial https://www.pygame.org/docs/tut/camera/CameraIntro.html

I hope this will works for you

Memik
  • 117
  • 9
4

You can do this with the 'pygame.image.frombuffer' command.

Here's an example:

import picamera
import pygame
import io

# Init pygame 
pygame.init()
screen = pygame.display.set_mode((0,0))

# Init camera
camera = picamera.PiCamera()
camera.resolution = (1280, 720)
camera.crop = (0.0, 0.0, 1.0, 1.0)

x = (screen.get_width() - camera.resolution[0]) / 2
y = (screen.get_height() - camera.resolution[1]) / 2

# Init buffer
rgb = bytearray(camera.resolution[0] * camera.resolution[1] * 3)

# Main loop
exitFlag = True
while(exitFlag):
    for event in pygame.event.get():
        if(event.type is pygame.MOUSEBUTTONDOWN or 
           event.type is pygame.QUIT):
            exitFlag = False

    stream = io.BytesIO()
    camera.capture(stream, use_video_port=True, format='rgb')
    stream.seek(0)
    stream.readinto(rgb)
    stream.close()
    img = pygame.image.frombuffer(rgb[0:
          (camera.resolution[0] * camera.resolution[1] * 3)],
           camera.resolution, 'RGB')

    screen.fill(0)
    if img:
        screen.blit(img, (x,y))

    pygame.display.update()

camera.close()
pygame.display.quit()
brentlance
  • 2,189
  • 1
  • 19
  • 25
  • 1
    thank you - this is really nice because you can explicitly set the sensor_mode of the camera, rather than use the pygame generic V4L2 driver which doesn't do so. Worked well for me. – danmcb Sep 24 '19 at 11:46