Display jpg, png, bmp etc

part 1: looking for an example to show a bmp or simular all i am finding is streaming etc

part 2: api to daw lines and circles in that image or on screen

another example would be to show a plot from matlab

on the hdmi out

HDMI uses a framebuffer. You can find a notebook example that shows how to manipulate the framebuffer here:

I’m not sure about an API or the best way to do this, and it probably depends on exactly what you want to do and if performance is a critical criteria.
If you search for ways to do this in Python you’ll probably find lots of suggestions. OpenCV may work for you. It is used in the example notebook.
You probably mean how to show a plot from Matplotlib, or some other plotting package.
Unless you have to use Matplotlib, you might find plotly performance is better. You can export to static image, so you could use this to output to the HDMI.
There may be better ways to do this so I’d suggest you do your own background research on this.
It would be great if you could post back your findings.


I’ve explored the solution proposed by Cathal and here is what I found.

I tried to use plotly, but it required othe libraries to exporte the static image. I decided to stay within the confine of matplotlib. As suggested, I also used OpenCV library.

Basically, I loaded everything as usual in Jupyter:

from pynq.overlays.base import BaseOverlay
from pynq.lib.video import *
base = BaseOverlay("base.bit")
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

I then started the hdmi driver using a resolution of 1280x1024, 24 bit colors and an fps of 30Hz:

frame_in_w = 1280
frame_in_h = 1024
Mode = VideoMode(frame_in_w,frame_in_h,24,fps=30)
hdmi_out = base.video.hdmi_out

After that, I created a variable containing a black image:

img = np.zeros((frame_in_h,frame_in_w,3), np.uint8)

Using the OpenCV library, the following code draw on the variable containing the black background a line, a circle and some text. Please note that the colors are in BRG instead of RGB.

# Draw a diagonal blue line with thickness of 5 px
# Create a circle
cv.circle(img,(0,0), 63, (0,0,255), -1)
# Write some text on the screen
cv.putText(img,'Hello!!!',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)

Finally, I sent to the HDMI buffer the image variable:

# Output image
outframe = hdmi_out.newframe()
outframe[:] = img

More detail on the syntax of the OpenCV code can be found on their website.

After that, I wrote this code that allows the plot of matplotlib to be shown on the monitor (the function that allow conversion of an RGBA image to RGB has bee take from the website shown below):

#Function that convert rgba to rgb
# Taken from https://stackoverflow.com/questions/50331463/convert-rgba-to-rgb-in-python
def rgba2rgb( rgba, background=(255,255,255) ):
    row, col, ch = rgba.shape

    if ch == 3:
        return rgba

    assert ch == 4, 'RGBA image has 4 channels.'

    rgb = np.zeros( (row, col, 3), dtype='float32' )
    r, g, b, a = rgba[:,:,0], rgba[:,:,1], rgba[:,:,2], rgba[:,:,3]

    a = np.asarray( a, dtype='float32' ) / 255.0

    R, G, B = background

    rgb[:,:,0] = r * a + (1.0 - a) * R
    rgb[:,:,1] = g * a + (1.0 - a) * G
    rgb[:,:,2] = b * a + (1.0 - a) * B

    return np.asarray( rgb, dtype='uint8' )

# Beginning of the code
# This line prevent Jupyter to display the plot. It can be removed without changing the behavior on the HDMI output
# Construction of x and y to be plotted
x = np.linspace(0, 3*np.pi, 500)
y = np.sin(x**2)

# Display of the plot using matplotlib
fig = plt.figure(figsize=(6.4, 5.12), dpi=200)
plt.plot(x, y)
plt.title('A simple chirp')
# The code will create the image finally stored in Y (in RGB content)
X = np.array(fig.canvas.renderer._renderer)
Y = rgba2rgb(X)
# Convert from rgb to bgr
Y = Y[:, :, ::-1]
# Output to the HDMI buffer
outframe = hdmi_out.newframe()
outframe[:] = Y

Hope this helps!

1 Like