Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

python 2.7 - Show an image with omxiv direct from memory on RPI

I want to create an image in PILLOW and show it on the screen on the Raspberry Pi with for example omxiv direct from memory without saving it to the memory card, something like this:

Python 2.7:

from PIL import Image
import os

img = Image.new('RGB', size=(150, 50), color=(0, 0, 255))
....
im_file = ????
os.system('omxiv im_file')

Can anybody tell me how to do this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I did some experiments with the framebuffer on my Raspberry Pi 4. Here is what I managed to work out...

You can get the screen resolution using the fbset command like this:

fbset -fb /dev/fb0 

Sample Output

mode "1280x1024"
    geometry 1280 1024 1280 1024 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

That tells me the screen is 1280 px wide and 1024 px high and I need to write 4 bytes per pixel in the order BGRA888.


So, I can do a quick test with ImageMagick to see if I can fill the screen, like this:

# Write to screen buffer - BGRA8888, width=1280, height=1024
convert -size 1280x1024 -depth 8 gradient:lime-magenta  bgra:/dev/fb0

and it fills the screen with a lime-magenta gradient. Excellent!


So, having acquired that knowledge and a smattering of confidence, let's try Python...

#!/usr/bin/env python3

import numpy as np

# Map the screen as Numpy array
# N.B. Numpy stores in format HEIGHT then WIDTH, not WIDTH then HEIGHT!
# c is the number of channels, 4 because BGRA
h, w, c = 1024, 1280, 4
fb = np.memmap('/dev/fb0', dtype='uint8',mode='w+', shape=(h,w,c)) 

# Fill entire screen with blue - takes 29 ms on Raspi 4
fb[:] = [255,0,0,255]

# Fill top half with red - takes 15 ms on Raspi 4
fb[:h//2] = [0,0,255,255]

# Fill bottom right quarter with green - takes 7 ms on Raspi 4
fb[h//2:, w//2:] = [0,255,0,255] 

I then tried displaying an image - Lena, of course. So, just for brevity and simplicity, I made Lena exactly the right size and added an alpha channel with ImageMagick:

convert lena.png -resize 1280x1024! -alpha opaque png32:lena1280.png

Then carried on as follows in the Python session I started above:

from PIL import Image

# Load Lena image
im = Image.open('/home/pi/lena1280.png') 

# Convert from PIL Image to Numpy array
n = np.array(im)

# Blit to screen - takes 30ms
fp[:] = n

Note that you would probably do better using OpenCV to load the image, with cv.imread(...,cv.IMREAD_UNCHANGED), because that will deliver you a Numpy array directly without needing conversion and the BGR ordering will already match that of the frame buffer.


Other useful commands - for my own reference!

# Retrieve EDID settings from monitor and write into a file called "edid"
tvservice -d edid

# Parse the file we just created to see what the attached monitor is capable of
edidparser edid

Sample Output

Enabling fuzzy format match...
Parsing edid...
HDMI:EDID version 1.3, 0 extensions, screen size 38x30 cm
HDMI:EDID features - videodef 0x80 standby suspend active off; colour encoding:RGB444|YCbCr444|YCbCr422; sRGB is default colourspace; preferred format is native; does not support GTF
HDMI:EDID found monitor S/N descriptor tag 0xff
HDMI:EDID found monitor name descriptor tag 0xfc
HDMI:EDID monitor name is DELL_1907FP
HDMI:EDID found monitor range descriptor tag 0xfd
HDMI:EDID monitor range offsets: V min=0, V max=0, H min=0, H max=0
HDMI:EDID monitor range: vertical is 56-76 Hz, horizontal is 30-81 kHz, max pixel clock is 140 MHz
HDMI:EDID monitor range does not support GTF
HDMI:EDID found preferred DMT detail timing format: 1280x1024p @ 60 Hz (35)
HDMI:EDID established timing I/II bytes are A5 4B 00
HDMI:EDID found DMT format: code 4, 640x480p @ 60 Hz in established timing I/II
HDMI:EDID found DMT format: code 6, 640x480p @ 75 Hz in established timing I/II
HDMI:EDID found DMT format: code 9, 800x600p @ 60 Hz in established timing I/II
HDMI:EDID found DMT format: code 11, 800x600p @ 75 Hz in established timing I/II
HDMI:EDID found DMT format: code 16, 1024x768p @ 60 Hz in established timing I/II
HDMI:EDID found DMT format: code 18, 1024x768p @ 75 Hz in established timing I/II
HDMI:EDID found DMT format: code 36, 1280x1024p @ 75 Hz in established timing I/II
HDMI:EDID standard timings block x 8: 0x714F 8180 0101 0101 0101 0101 0101 0101 
HDMI:EDID found DMT format: code 21, 1152x864p @ 75 Hz (4:3) in standard timing 0
HDMI:EDID found DMT format: code 35, 1280x1024p @ 60 Hz (5:4) in standard timing 1
HDMI:EDID filtering formats with pixel clock unlimited MHz or h. blanking unlimited
HDMI:EDID best score mode initialised to DMT (4) 640x480p @ 60 Hz with pixel clock 25 MHz (score 0)
HDMI:EDID best score mode is now DMT (4) 640x480p @ 60 Hz with pixel clock 25 MHz (score 36864)
HDMI:EDID DMT mode (6) 640x480p @ 75 Hz with pixel clock 31 MHz has a score of 11520
HDMI:EDID best score mode is now DMT (9) 800x600p @ 60 Hz with pixel clock 40 MHz (score 57600)
HDMI:EDID DMT mode (11) 800x600p @ 75 Hz with pixel clock 49 MHz has a score of 18000
HDMI:EDID best score mode is now DMT (16) 1024x768p @ 60 Hz with pixel clock 65 MHz (score 94370)
HDMI:EDID DMT mode (18) 1024x768p @ 75 Hz with pixel clock 78 MHz has a score of 29491
HDMI:EDID DMT mode (21) 1152x864p @ 75 Hz with pixel clock 108 MHz has a score of 62324
HDMI:EDID best score mode is now DMT (35) 1280x1024p @ 60 Hz with pixel clock 108 MHz (score 5260929)
HDMI:EDID DMT mode (36) 1280x1024p @ 75 Hz with pixel clock 135 MHz has a score of 49152
HDMI0:EDID preferred mode remained as DMT (35) 1280x1024p @ 60 Hz with pixel clock 108 MHz
HDMI:EDID has only DVI support and no audio support
edidparser exited with code 0

You can turn off/disbale the text cursor in the console like this:

sudo sh -c "TERM=linux setterm -foreground black -clear all >/dev/tty0"

and re-enable it like this:

sudo sh -c "TERM=linux setterm -foreground white -clear all >/dev/tty0"

Keywords: Raspberry Pi, RasPi, framebuffer, fb0, /dev/fb0, Python, Numpy, ImageMagick, direct frame buffer access, edid, HDMI, DVI, monitor capabilities, features, tvservice, edidparser, resolution, bgra8888, blit, bit-blit, cursor


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...