Compare commits
4 commits
dd77450f15
...
985d72ceb9
| Author | SHA1 | Date | |
|---|---|---|---|
| 985d72ceb9 | |||
|
|
248c59ae2a | ||
|
|
c886a13fd6 | ||
|
|
22ad9aa7df |
10 changed files with 107 additions and 96 deletions
|
|
@ -34,13 +34,13 @@ with open("/sys/class/graphics/fb0/stride") as f:
|
|||
linux_framebuffer = np.memmap('/dev/fb0',mode='r', shape=(screeny, stride // bytes_per_pixel), dtype=dtype)
|
||||
|
||||
@click.command
|
||||
@click.option("--x-offset", "xoffset", type=int, help="The x offset of top left corner of the region to mirror")
|
||||
@click.option("--y-offset", "yoffset", type=int, help="The y offset of top left corner of the region to mirror")
|
||||
@click.option("--x-offset", "xoffset", type=int, help="The x offset of top left corner of the region to mirror", default=0)
|
||||
@click.option("--y-offset", "yoffset", type=int, help="The y offset of top left corner of the region to mirror", default=0)
|
||||
@piomatter_click.standard_options
|
||||
def main(xoffset, yoffset, width, height, serpentine, rotation, colorspace, pinout, n_planes, n_addr_lines):
|
||||
def main(xoffset, yoffset, width, height, serpentine, rotation, pinout, n_planes, n_addr_lines):
|
||||
geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, rotation=rotation)
|
||||
framebuffer = np.zeros(shape=(geometry.height, geometry.width), dtype=dtype)
|
||||
matrix = piomatter.PioMatter(colorspace=colorspace, pinout=pinout, framebuffer=framebuffer, geometry=geometry)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB565, pinout=pinout, framebuffer=framebuffer, geometry=geometry)
|
||||
|
||||
while True:
|
||||
framebuffer[:,:] = linux_framebuffer[yoffset:yoffset+height, xoffset:xoffset+width]
|
||||
|
|
|
|||
|
|
@ -1,58 +1,47 @@
|
|||
#!/usr/bin/python3
|
||||
"""
|
||||
Mirror a scaled copy of the framebuffer to 64x32 matrices,
|
||||
Mirror a scaled copy of the framebuffer to RGB matrices,
|
||||
|
||||
The upper left corner of the framebuffer is displayed until the user hits ctrl-c.
|
||||
A portion of the framebuffer is displayed until the user hits ctrl-c.
|
||||
|
||||
Control scale, matrix size, and orientation with command line arguments.
|
||||
|
||||
python fbmirror_scaled.py [scale] [width] [height] [orientation]
|
||||
Usage: fbmirror_scaled.py [OPTIONS]
|
||||
|
||||
Options:
|
||||
--x-offset INTEGER The x offset of top left corner of the
|
||||
region to mirror
|
||||
--y-offset INTEGER The y offset of top left corner of the
|
||||
region to mirror
|
||||
--scale INTEGER The scale factor to reduce the display down
|
||||
by.
|
||||
--num-address-lines INTEGER The number of address lines used by the
|
||||
panels
|
||||
--num-planes INTEGER The number of bit planes (color depth. Lower
|
||||
values can improve refresh rate in frames
|
||||
per second
|
||||
--orientation [Normal|R180|CCW|CW]
|
||||
The overall orientation (rotation) of the
|
||||
panels
|
||||
--pinout [AdafruitMatrixBonnet|AdafruitMatrixBonnetBGR|AdafruitMatrixHat|AdafruitMatrixHatBGR]
|
||||
The details of the electrical connection to
|
||||
the panels
|
||||
--serpentine / --no-serpentine The organization of multiple panels
|
||||
--height INTEGER The panel height in pixels
|
||||
--width INTEGER The panel width in pixels
|
||||
--help Show this message and exit.
|
||||
|
||||
scale int: How many times to scale down the display framebuffer. Default is 3.
|
||||
width int: Total width of matrices in pixels. Default is 64.
|
||||
height int: Total height of matrices in pixels. Default is 32.
|
||||
orientation int: Orientation in degrees, must be 0, 90, 180, or 270.
|
||||
Default is 0 or Normal orientation.
|
||||
|
||||
The `/dev/fb0` special file will exist if a monitor is plugged in at boot time,
|
||||
or if `/boot/firmware/cmdline.txt` specifies a resolution such as
|
||||
`... video=HDMI-A-1:640x480M@60D`.
|
||||
"""
|
||||
import sys
|
||||
|
||||
import adafruit_raspberry_pi5_piomatter
|
||||
import adafruit_raspberry_pi5_piomatter as piomatter
|
||||
import click
|
||||
import numpy as np
|
||||
import PIL.Image as Image
|
||||
|
||||
if len(sys.argv) >= 2:
|
||||
scale = int(sys.argv[1])
|
||||
else:
|
||||
scale = 3
|
||||
|
||||
if len(sys.argv) >= 3:
|
||||
width = int(sys.argv[2])
|
||||
else:
|
||||
width = 64
|
||||
|
||||
if len(sys.argv) >= 4:
|
||||
height = int(sys.argv[3])
|
||||
else:
|
||||
height = 32
|
||||
|
||||
if len(sys.argv) >= 5:
|
||||
rotation = int(sys.argv[4])
|
||||
if rotation == 90:
|
||||
rotation = adafruit_raspberry_pi5_piomatter.Orientation.CW
|
||||
elif rotation == 180:
|
||||
rotation = adafruit_raspberry_pi5_piomatter.Orientation.R180
|
||||
elif rotation == 270:
|
||||
rotation = adafruit_raspberry_pi5_piomatter.Orientation.CCW
|
||||
elif rotation == 0:
|
||||
rotation = adafruit_raspberry_pi5_piomatter.Orientation.Normal
|
||||
else:
|
||||
raise ValueError("Invalid rotation. Must be 0, 90, 180, or 270.")
|
||||
else:
|
||||
rotation = adafruit_raspberry_pi5_piomatter.Orientation.Normal
|
||||
import piomatter_click
|
||||
|
||||
with open("/sys/class/graphics/fb0/virtual_size") as f:
|
||||
screenx, screeny = [int(word) for word in f.read().split(",")]
|
||||
|
|
@ -70,26 +59,33 @@ with open("/sys/class/graphics/fb0/stride") as f:
|
|||
|
||||
linux_framebuffer = np.memmap('/dev/fb0',mode='r', shape=(screeny, stride // bytes_per_pixel), dtype=dtype)
|
||||
|
||||
xoffset = 0
|
||||
yoffset = 0
|
||||
|
||||
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=width, height=height, n_addr_lines=4, rotation=rotation)
|
||||
matrix_framebuffer = np.zeros(shape=(geometry.height, geometry.width, 3), dtype=np.uint8)
|
||||
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(matrix_framebuffer, geometry)
|
||||
@click.command
|
||||
@click.option("--x-offset", "xoffset", type=int, help="The x offset of top left corner of the region to mirror", default=0)
|
||||
@click.option("--y-offset", "yoffset", type=int, help="The y offset of top left corner of the region to mirror", default=0)
|
||||
@click.option("--scale", "scale", type=int, help="The scale factor to reduce the display down by.", default=3)
|
||||
@piomatter_click.standard_options
|
||||
def main(xoffset, yoffset, scale, width, height, serpentine, rotation, pinout, n_planes, n_addr_lines):
|
||||
geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, rotation=rotation)
|
||||
matrix_framebuffer = np.zeros(shape=(geometry.height, geometry.width, 3), dtype=np.uint8)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed, pinout=pinout, framebuffer=matrix_framebuffer, geometry=geometry)
|
||||
|
||||
while True:
|
||||
tmp = linux_framebuffer[yoffset:yoffset+height*scale, xoffset:xoffset+width*scale]
|
||||
# Convert the RGB565 framebuffer into RGB888Packed (so that we can use PIL image operations to rescale it)
|
||||
r = (tmp & 0xf800) >> 8
|
||||
r = r | (r >> 5)
|
||||
r = r.astype(np.uint8)
|
||||
g = (tmp & 0x07e0) >> 3
|
||||
g = g | (g >> 6)
|
||||
g = g.astype(np.uint8)
|
||||
b = (tmp & 0x001f) << 3
|
||||
b = b | (b >> 5)
|
||||
b = b.astype(np.uint8)
|
||||
img = Image.fromarray(np.stack([r, g, b], -1))
|
||||
img = img.resize((width, height))
|
||||
matrix_framebuffer[:,:] = np.asarray(img)
|
||||
matrix.show()
|
||||
while True:
|
||||
tmp = linux_framebuffer[yoffset:yoffset + height * scale, xoffset:xoffset + width * scale]
|
||||
# Convert the RGB565 framebuffer into RGB888Packed (so that we can use PIL image operations to rescale it)
|
||||
r = (tmp & 0xf800) >> 8
|
||||
r = r | (r >> 5)
|
||||
r = r.astype(np.uint8)
|
||||
g = (tmp & 0x07e0) >> 3
|
||||
g = g | (g >> 6)
|
||||
g = g.astype(np.uint8)
|
||||
b = (tmp & 0x001f) << 3
|
||||
b = b | (b >> 5)
|
||||
b = b.astype(np.uint8)
|
||||
img = Image.fromarray(np.stack([r, g, b], -1))
|
||||
img = img.resize((width, height))
|
||||
matrix_framebuffer[:, :] = np.array(img)
|
||||
matrix.show()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ def standard_options(
|
|||
height=32,
|
||||
serpentine=True,
|
||||
rotation=piomatter.Orientation.Normal,
|
||||
colorspace=piomatter.Colorspace.RGB888,
|
||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||
n_planes=10,
|
||||
n_addr_lines=4,
|
||||
|
|
@ -58,13 +57,6 @@ def standard_options(
|
|||
f = click.option("--height", default=height, help="The panel height in pixels")(f)
|
||||
if serpentine is not None:
|
||||
f = click.option("--serpentine/--no-serpentine", default=serpentine, help="The organization of multiple panels")(f)
|
||||
if colorspace is not None:
|
||||
f = click.option(
|
||||
"--colorspace",
|
||||
default=colorspace,
|
||||
type=PybindEnumChoice(piomatter.Colorspace),
|
||||
help="The memory organization of the framebuffer"
|
||||
)(f)
|
||||
if pinout is not None:
|
||||
f = click.option(
|
||||
"--pinout",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ The animated gif is played repeatedly until interrupted with ctrl-c.
|
|||
|
||||
import time
|
||||
|
||||
import adafruit_raspberry_pi5_piomatter
|
||||
import adafruit_raspberry_pi5_piomatter as piomatter
|
||||
import numpy as np
|
||||
import PIL.Image as Image
|
||||
|
||||
|
|
@ -21,9 +21,13 @@ height = 32
|
|||
gif_file = "nyan.gif"
|
||||
|
||||
canvas = Image.new('RGB', (width, height), (0, 0, 0))
|
||||
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=width, height=height, n_addr_lines=4, rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
|
||||
geometry = piomatter.Geometry(width=width, height=height,
|
||||
n_addr_lines=4, rotation=piomatter.Orientation.Normal)
|
||||
framebuffer = np.asarray(canvas) + 0 # Make a mutable copy
|
||||
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
|
||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||
framebuffer=framebuffer,
|
||||
geometry=geometry)
|
||||
|
||||
with Image.open(gif_file) as img:
|
||||
print(f"frames: {img.n_frames}")
|
||||
|
|
|
|||
|
|
@ -13,16 +13,19 @@ import glob
|
|||
import sys
|
||||
import time
|
||||
|
||||
import adafruit_raspberry_pi5_piomatter
|
||||
import adafruit_raspberry_pi5_piomatter as piomatter
|
||||
import numpy as np
|
||||
import PIL.Image as Image
|
||||
|
||||
images = sorted(glob.glob(sys.argv[1]))
|
||||
|
||||
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=64, height=32, n_addr_lines=4, rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
|
||||
geometry = piomatter.Geometry(width=64, height=32, n_addr_lines=4, rotation=piomatter.Orientation.Normal)
|
||||
framebuffer = np.asarray(Image.open(images[0])) + 0 # Make a mutable copy
|
||||
nimages = len(images)
|
||||
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
|
||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||
framebuffer=framebuffer,
|
||||
geometry=geometry)
|
||||
|
||||
while True:
|
||||
t0 = time.monotonic()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ $ python quote_scroller.py
|
|||
|
||||
"""
|
||||
|
||||
import adafruit_raspberry_pi5_piomatter
|
||||
import adafruit_raspberry_pi5_piomatter as piomatter
|
||||
import numpy as np
|
||||
import requests
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
|
@ -44,10 +44,14 @@ full_txt_img.save("quote.png")
|
|||
|
||||
single_frame_img = Image.new("RGB", (total_width, total_height), (0, 0, 0))
|
||||
|
||||
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=total_width, height=total_height, n_addr_lines=4, rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
|
||||
geometry = piomatter.Geometry(width=total_width, height=total_height,
|
||||
n_addr_lines=4, rotation=piomatter.Orientation.Normal)
|
||||
framebuffer = np.asarray(single_frame_img) + 0 # Make a mutable copy
|
||||
|
||||
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
|
||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||
framebuffer=framebuffer,
|
||||
geometry=geometry)
|
||||
|
||||
print("Ctrl-C to exit")
|
||||
while True:
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
Display a simple test pattern of 3 shapes on a single 64x32 matrix panel.
|
||||
Display a spiral around the display drawn with a rainbow color.
|
||||
|
||||
Run like this:
|
||||
|
||||
$ python simpletest.py
|
||||
$ python rainbow_spiral.py
|
||||
|
||||
"""
|
||||
import adafruit_raspberry_pi5_piomatter
|
||||
import adafruit_raspberry_pi5_piomatter as piomatter
|
||||
import numpy as np
|
||||
import rainbowio
|
||||
from PIL import Image, ImageDraw
|
||||
|
|
@ -23,10 +23,13 @@ pen_radius = 1
|
|||
canvas = Image.new('RGB', (width, height), (0, 0, 0))
|
||||
draw = ImageDraw.Draw(canvas)
|
||||
|
||||
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=width, height=height, n_addr_lines=4,
|
||||
rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
|
||||
geometry = piomatter.Geometry(width=width, height=height, n_addr_lines=4,
|
||||
rotation=piomatter.Orientation.Normal)
|
||||
framebuffer = np.asarray(canvas) + 0 # Make a mutable copy
|
||||
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
|
||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||
framebuffer=framebuffer,
|
||||
geometry=geometry)
|
||||
|
||||
color_index = 0
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,16 @@ The image is displayed until the user hits enter to exit.
|
|||
|
||||
import pathlib
|
||||
|
||||
import adafruit_raspberry_pi5_piomatter
|
||||
import adafruit_raspberry_pi5_piomatter as piomatter
|
||||
import numpy as np
|
||||
import PIL.Image as Image
|
||||
|
||||
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=64, height=64, n_addr_lines=4, rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
|
||||
geometry = piomatter.Geometry(width=64, height=64, n_addr_lines=4, rotation=piomatter.Orientation.Normal)
|
||||
framebuffer = np.asarray(Image.open(pathlib.Path(__file__).parent / "blinka64x64.png"))
|
||||
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
|
||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||
framebuffer=framebuffer,
|
||||
geometry=geometry)
|
||||
matrix.show()
|
||||
|
||||
input("Hit enter to exit")
|
||||
|
|
|
|||
|
|
@ -11,23 +11,27 @@ $ python simpletest.py
|
|||
|
||||
"""
|
||||
|
||||
import adafruit_raspberry_pi5_piomatter
|
||||
import adafruit_raspberry_pi5_piomatter as piomatter
|
||||
import numpy as np
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
width = 64
|
||||
height = 32
|
||||
|
||||
geometry = adafruit_raspberry_pi5_piomatter.Geometry(width=width, height=height, n_addr_lines=4, rotation=adafruit_raspberry_pi5_piomatter.Orientation.Normal)
|
||||
geometry = piomatter.Geometry(width=width, height=height, n_addr_lines=4,
|
||||
rotation=piomatter.Orientation.Normal)
|
||||
|
||||
canvas = Image.new('RGB', (width, height), (0, 0, 0))
|
||||
draw = ImageDraw.Draw(canvas)
|
||||
|
||||
framebuffer = np.asarray(canvas) + 0 # Make a mutable copy
|
||||
matrix = adafruit_raspberry_pi5_piomatter.AdafruitMatrixBonnetRGB888Packed(framebuffer, geometry)
|
||||
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
|
||||
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
|
||||
framebuffer=framebuffer,
|
||||
geometry=geometry)
|
||||
|
||||
draw.rectangle((2,2, 10,10), fill=0x008800)
|
||||
draw.circle((18,6), 4, fill=0x880000)
|
||||
draw.rectangle((2, 2, 10, 10), fill=0x008800)
|
||||
draw.circle((18, 6), 4, fill=0x880000)
|
||||
draw.polygon([(28, 2), (32, 10), (24, 10)], fill=0x000088)
|
||||
|
||||
framebuffer[:] = np.asarray(canvas)
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ PYBIND11_MODULE(adafruit_raspberry_pi5_piomatter, m) {
|
|||
:toctree: _generate
|
||||
|
||||
Orientation
|
||||
Pinout
|
||||
Colorspace
|
||||
Geometry
|
||||
PioMatter
|
||||
AdafruitMatrixBonnetRGB888
|
||||
|
|
|
|||
Loading…
Reference in a new issue