← index #15275Issue #15944
Related · high · value 2.746
QUERY · ISSUE

Cannot instantiate FrameBuffer from a bytes object

openby peterhinchopened 2024-06-13updated 2026-03-20
bugextmod

Port, board and/or hardware

RP2, Pyboard 1.1

MicroPython version

MicroPython v1.22.1 on 2024-01-05; Raspberry Pi Pico with RP2040

Reproduction

Enter the following at the REPL:

from framebuf import FrameBuffer, GS8
b = b'\x00' * 100
f = FrameBuffer(b, 10, 10, GS8)

Expected behaviour

I would expect the instantiation of the FrameBuffer to succeed (as it does if a bytearray is passed).

Observed behaviour

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object with buffer protocol required

Additional Information

Use case:
Instantiating from a bytes object (or a memoryview of bytes) would enable graphical objects frozen as bytecode to be blitted onto an existing frame buffer.

A further observation: the error message is most misleading.

Code of Conduct

Yes, I agree

CANDIDATE · ISSUE

FrameBuffer Initialisation fails with ValueError on `memoryview`

closedby corranwebsteropened 2024-10-01updated 2024-10-22
bug

Port, board and/or hardware

RP2; Unix (but I believe this affects any board with framebuffer support)

MicroPython version

MicroPython v1.23.0 on 2024-06-02; Raspberry Pi Pico with RP2040

Reproduction

Run the code below in the REPL, or run a script with the same code in it:

import array
import framebuf
buf = array.array('H', bytearray(2*8*8))
sub_buf = memoryview(buf)[4:]
fbuf = framebuf.FrameBuffer(sub_buf, 4, 8, framebuf.RGB565, 8)

Expected behaviour

I expected the code to work without error.

Observed behaviour

I get an unexpected ValueError with no explanation:

>>> import array
>>> import framebuf
>>> buf = array.array('H', bytearray(2*8*8))
>>> sub_buf = memoryview(buf)[4:]
>>> fbuf = framebuf.FrameBuffer(sub_buf, 4, 8, framebuf.RGB565, 8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 

Additional Information

The "what am I actually trying to do" here is to create a frame buffer on a subsection of another buffer using a memory view to avoid copying data, either:

  • to clip out a sprite from a larger sprite-sheet buffer to display using FrameBuffer.blit
  • to clip drawing to a sub-region of a larger image (for this you have to have a memory view into the same underlying buffer)

This is likely related to, but different from #15571, as that is an issue with bit-alignment. As with that issue, I think that the lines at fault are here: https://github.com/micropython/micropython/blob/17d82344581ad3a76033fae54c5d3304e17f185f/extmod/modframebuf.c#L317-L319

If you look at the underlying buffers, you have something like the following:

....xxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx

where . are values in the underlying buffer that are skipped by the memoryview, x are values that should be visible in the framebuffer, and s are values which are skipped by the stride of 8.

It appears that what the FrameBuffer code is expecting is the following:

....xxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssss

even though the last 4 values are never written to.

Work-around

This can be worked around by allocating extra memory to the underlying buffer, although that's fiddly for the first use-case if the data is loaded from an existing sprite sheet buffer, eg. loaded from a file.

Code of Conduct

Yes, I agree

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied