display image on framebuffer, then quit?


18 posts
by jbeale » Wed Oct 09, 2013 11:18 pm
This isn't really a Python question, it's a basic image display question. I want to capture an image, display it on the console framebuffer (note: not using X Windows) and then quit after a few seconds. The below python code almost works. Well it does work, but afterwards it leaves the framebuffer stuck on the image, it does not return to the text console. If I then blindly type 'fbi test.jpg' to restart it and then manually quit, it leaves me a completely blank screen, no text or anything. All I know how to do at this point is reboot the Pi to restore the screen. Is there an easy way around this, either to reset the framebuffer to the text console, or close the 'fbi' program correctly?

Code: Select all
cmd1 = "raspistill -t 2000 -o test.jpg"
cmd2 = "fbi test.jpg"

subprocess.Popen(cmd1.split())          # start image capture
time.sleep(2.7)                         # wait this long for the image to be captured
proc1 = subprocess.Popen(cmd2.split())  # display the result on framebuffer
time.sleep(2)                           # ... for this long...
proc1.kill()                            # and then quit


EDIT: maybe the right approach is to use 'Pygame' which can apparently use the framebuffer with or without X running. Checking out http://learn.adafruit.com/pi-video-outp ... ramebuffer ...ah yes, that works.
User avatar
Posts: 3251
Joined: Tue Nov 22, 2011 11:51 pm
by jbeale » Wed Oct 09, 2013 11:51 pm
Sure enough, after copying over the pyscope class from above Adafruit link, below code works:
Code: Select all
import os, pygame, time
class pyscope :
# class def. from http://learn.adafruit.com/pi-video-output-using-pygame/pointing-pygame-to-the-framebuffer
# blah, blah...

scope = pyscope()
image1 = pygame.image.load('test.jpg').convert()
isize = image1.get_size()
dsize = (pygame.display.Info().current_w, pygame.display.Info().current_h)
xp = (dsize[0] - isize[0]) / 2  # find location to center image on screen
yp = (dsize[1] - isize[1]) / 2
scope.screen.blit(image1,(xp,yp))
pygame.display.update()
time.sleep(3)
User avatar
Posts: 3251
Joined: Tue Nov 22, 2011 11:51 pm
by howardwatkins » Sun Nov 16, 2014 1:25 pm
Like the original poster, I am using fbi from a python script. When the program quits, it leaves the last image on my Adafruit PiTFT display, but I want to return to displaying text as on a console.

Does anyone have any idea how to do this? I agree pygame works, but I want to use fbi.

Howard.
Posts: 3
Joined: Sun Nov 16, 2014 1:21 pm
by howardwatkins » Sun Nov 16, 2014 6:32 pm
OK, I've found a partial solution.

If I run my python application and display 9 images (some repeated), then when the program finishes "ps -ef" shows 9 fbi processes still running, and "pgrep fbi" shows the process ids of all 9. However "sudo pkill fbi" only kills 8, leaving the first one still present (as shown by both "ps -ef" & "pgrep fbi").

A further "sudo pkill fbi" has no effect, but if I do a "sudo kill -2 ID" (where ID is the process id) it kills the remaining process AND I get the text displayed on my Adafruit PiTFT display.

I repeated the experiment with the same 9 images and did a "sudo pkill -o fbi" (to kill the oldest process) followed by "sudo pkill fbi" and that worked.

However when I repeated the test again, I had no fbi processes running but the display still showed an image. So it seems to work some of the time.

Anybody got any ideas?
Howard.
Posts: 3
Joined: Sun Nov 16, 2014 1:21 pm
by howardwatkins » Wed Jan 07, 2015 10:34 am
Rather than kill the oldest process running fbi, is there a way to get the single running fbi process to display a different image?

Note, I am not trying to make a slideshow, or display the images randomly. I am using an RFID reader and wish to display an image associated with the last tag that was read.

Howard.
Posts: 3
Joined: Sun Nov 16, 2014 1:21 pm
by fabienbure » Sun Jan 24, 2016 2:15 pm
Hi Howard

I have the same problem...i am running a phython program, i have a loop waiting for an inetrruption (button pressed), then i take a picture with an usb webcam, i show the picture....but after 5s i want to come back to my loop for the next photo.

did you find a solution to your problem ?

thanks

Fabien
Posts: 2
Joined: Sun Jan 24, 2016 2:07 pm
by elParaguayo » Sun Jan 24, 2016 4:57 pm
Want to share your code?
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.
User avatar
Posts: 1793
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK
by stderr » Sun Jan 24, 2016 6:01 pm
fabienbure wrote:I have the same problem...i am running a phython program, i have a loop waiting for an inetrruption (button pressed), then i take a picture with an usb webcam, i show the picture....but after 5s i want to come back to my loop for the next photo.

You could loop the display of whatever the latest image is with one program and then wait for keyboard input with another to get the next picture. In any case, you need some sort of framebuffer program that can display something and quit while leaving the picture on the display. I think that fbi erases it.

If there is a loop in the framebuffer display program that, say, gets pics for a slideshow or some other thing that you don't want, you might have to find the source and gut that part of the thing. It gets harder if it is using a library that insists on doing things deeply inside itself that you don't want.
Posts: 2173
Joined: Sat Dec 01, 2012 11:29 pm
by bullwinkle » Sun Jan 24, 2016 8:22 pm
Hello

I was looking at FBI today to use with Python but had trouble as noted above.

FBI is a good program, but like others, I'm looking for something basic just to push an image to the fb.

I found
Code: Select all
dd if=background.fb of=/dev/fb1 bs=153600 count=1 >/dev/null 2>&1
worked ok if I have an image in raw format. But I'm having trouble to find something to create the raw format (i guess fbi does it, but I've not looked at the code yet).

I tried imagemagick but could not get it to create the raw file for the dd comand.
Posts: 116
Joined: Wed Jan 09, 2013 12:14 pm
by fabienbure » Mon Jan 25, 2016 9:39 am
Code: Select all
#!/usr/bin/env python2.7
# -*- coding: latin-1 -*-
import RPi.GPIO as GPIO
import time
import os
from datetime import datetime
import Image

GPIO.setmode(GPIO.BCM)

GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#definition et init des variables
date_today = datetime.now()

nom_courant = date_today.date()
nom_courant = nom_courant.strftime('%d_%m_%Y') #on recupere la date du jour pour nommer le dossier du jour
 

while True : #boucle jusqu'a interruption

        print "\n attente boucle"

        GPIO.wait_for_edge(23, GPIO.FALLING) #on attend que le bouton soit pressé
       
        # on a appuyé sur le bouton...
       
        if (os.path.isdir(nom_courant) == False): # si le dossier du jour n'existe pas
             
              print("le dossier existe\n")
 
              os.mkdir(nom_courant) # on crée le dossier du jour
             
              chemin_fichier = str(nom_courant+'/nb') #voici le chemin du fichier 'nb'
             
              filout = open(chemin_fichier,'w') #on cree 'nb'

              filout.write('0') # on ecrit le nombre de photo qu'il y a dans le repertoire
                                # soit "0" car on vient de créer le fichier

              filout.close()
 
             
        #si on est ici c'est que le dossier existe et que le fichier comptenant le nbr de photo du
        #dossier a été créé.

        #on commence par lire le fichier "nb" pour savoir combien il y a de photo
        #dans le repertoire du jour
       
        chemin_fichier = str(nom_courant+'/nb') #le chemin du fichier "nb"
       
        filin = open(chemin_fichier,'r') #on ouvre "nb" en lecture"

        nbr_fichier = int(filin.readline()) #on recupere le nombre (que l'on transforme en INT)

        filin.close() #on ferme le fichier "nb"

        #on prend la photo

        nombre_photo = nbr_fichier+1
         
        chemin_photo = '/home/pi/photobooth/'+nom_courant+'/'+ str(nombre_photo) + '.jpeg'
       
        os.system("fswebcam " + chemin_photo) #on photographie

        #on actualise le nombre de photo dans le fichier nb

        filout = open(nom_courant+'/nb','w')
       
        filout.write(str(nombre_photo))
       
        filout.close()
       
        #on affiche la photo

        os.system ("fbi " + chemin_photo) #on affiche la photo
           
               

GPIO.cleanup()           # reinitialisation GPIO lors d'une sortie normale



Here is my code, it's "working", but only for one picture, i don't know how to kill FBI to return to my loop...I think the solution will be to create 2 programs, one for listening, and one to execute the task...
Posts: 2
Joined: Sun Jan 24, 2016 2:07 pm
by elParaguayo » Mon Jan 25, 2016 1:59 pm
Does using subprocess (creating a Popen object and then killing it) not work?
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.
User avatar
Posts: 1793
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK
by -rst- » Mon Jan 25, 2016 5:16 pm
bullwinkle wrote:Hello

I was looking at FBI today to use with Python but had trouble as noted above.

FBI is a good program, but like others, I'm looking for something basic just to push an image to the fb.

I found
Code: Select all
dd if=background.fb of=/dev/fb1 bs=153600 count=1 >/dev/null 2>&1
worked ok if I have an image in raw format. But I'm having trouble to find something to create the raw format (i guess fbi does it, but I've not looked at the code yet).

I tried imagemagick but could not get it to create the raw file for the dd comand.


Imagemagick does not seem to support 16 bit raw RGB - the output using 'rgb:filename.raw' and 'filename.rgb' is always 32 bit RGBA :(

GIMP (possibly slow on RPi) can save a 16bit 5:6:5 file.

It should be fairly easy to write a small utility program to convert from say ppm format to raw rgb565... (use pngtopnm or jpegtopnm first)
Last edited by -rst- on Tue Jan 26, 2016 4:15 pm, edited 1 time in total.
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by bullwinkle » Mon Jan 25, 2016 6:41 pm
It should be fairly easy to write a small utility program to convert from say ppm format to raw rgb565... (use pngtopnm or jpegtopnm first)


I made some progress on this ....2 options:
1. ffmpeg. I thought this would be slow, but it is very fast
Code: Select all
ffmpeg -vcodec png -i input.png -vcodec rawvideo -f rawvideo -pix_fmt rgb565 output.raw
and then use dd to copy it into the framebuffer

2. modify the program from andyD - which works pretty well. thanks Andy!
https://github.com/AndrewFromMelbourne/sdl_image_example
to show on the ttf remember
Code: Select all
export SDL_FBDEV=/dev/fb1


Edit:
by -rst- »

I just realized who I was replying to ! Many thanks for your excellent tutorials on the FB. Nice work.
Posts: 116
Joined: Wed Jan 09, 2013 12:14 pm
by -rst- » Tue Jan 26, 2016 1:48 pm
Thanks :)

Starting from my fb examples would be easy to get the image to the fb but of course would need to find a simple way to read in the image first - libpng etc are not the simplest to just read in an image...

After leaving work yesterday it came to me that ffmpeg might do it - good to hear you found the same solution too. Wouldn't 'cat image.raw >/dev/fb1' work instead of 'dd'? Nothing wrong with dd, just simpler.

The SDL option is of course a good one - the IMG_Load is so handy and of course if you plan to extend to something more complex (sounds, mouse, etc.).
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by -rst- » Tue Jan 26, 2016 5:38 pm
Had some spare time and this felt like something worth trying...

Source code for a quick and dirty PNM to RGB565 converter: https://github.com/rst-/raspberry-compo ... aster/img/

Also added 320x240 pixel test images: original test24.png and converted test565.raw

Conversion commandline:
Code: Select all
pngtopnm /path/to/test24.png | /path/to/ppmtorgb565 > /path/to/test565.raw


Disclaimer: I have not compiled or run this on a Raspberry Pi - only tested on a Debian VirtualBox VM and output images verified using IrfanView on Windows.

Might be interesting to try direct to framebuffer:
Code: Select all
pngtopnm /path/to/image24.png | /path/to/ppmtorgb565 > /dev/fb1
...
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland
by bullwinkle » Wed Jan 27, 2016 5:33 am
by -rst- » Tue Jan 26, 2016 6:38 pm


thanks for the idea about "cat image.raw >/dev/fb1" - yes is is easier and less stuff to remember or bugger-up compared to dd.

I'll take a look at your new utility - I think it will be very useful judging from the number of people searching for a rgb565 converted. I'm surprised Imagemagick does not have this option as it has pretty much everything else!!

thanks again and cheers,
Posts: 116
Joined: Wed Jan 09, 2013 12:14 pm
by bullwinkle » Wed Jan 27, 2016 5:29 pm
I'll take a look at your new utility - I think it will be very useful judging from the number of people searching for a rgb565 converted.

it works. :)
compiled on the pi no problem. output to /dev/fb1 works too
friendly hat tip to you ...thanks
Posts: 116
Joined: Wed Jan 09, 2013 12:14 pm
by -rst- » Thu Jan 28, 2016 5:17 pm
Good to hear, thanks.
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
Posts: 1316
Joined: Thu Nov 01, 2012 12:12 pm
Location: Dublin, Ireland