Closed kekemuyu closed 2 months ago
My lcd is st7789. I made a try to display a picture with framebuf as your said. The effect is too bad to see it clearly.
color_setup.py:
import machine
import gc
# *** Choose your color display driver here ***
# Driver supporting non-STM platforms
# from drivers.ssd1351.ssd1351_generic import SSD1351 as SSD
# STM specific driver
from drivers.st7789.st7789_4bit import *
SSD=ST7789
#height = 96 # 1.27 inch 96*128 (rows*cols) display
machine.Pin(4, machine.Pin.OUT, value=1)
pdc = machine.Pin(22, machine.Pin.OUT, value=0)
pcs = machine.Pin(21, machine.Pin.OUT, value=1)
prst = machine.Pin(5, machine.Pin.OUT, value=1)
spi = machine.SPI(2)
gc.collect() # Precaution before instantiating framebuf
spi = machine.SPI(1, 30_000_000, sck=machine.Pin(18), mosi=machine.Pin(23))
ssd = SSD(spi, height=132, width=240, dc=pdc, cs=pcs, rst=prst, disp_mode=USD|REFLECT , display=TDISPLAY)
dis_bmp.py:
from color_setup import ssd
from gui.core.nanogui import refresh,fillcircle,circle
from gui.core.writer import Writer, CWriter
import gui.fonts.arial10 as arial10
from gui.core.colors import *
import framebuf
f=open('test.bmp', 'rb')
if f.read(2) == b'BM': #header
dummy = f.read(8) #file size(4), creator bytes(4)
offset = int.from_bytes(f.read(4), 'little')
hdrsize = int.from_bytes(f.read(4), 'little')
width = int.from_bytes(f.read(4), 'little')
height = int.from_bytes(f.read(4), 'little')
if int.from_bytes(f.read(2), 'little') == 1: #planes must be 1
depth = int.from_bytes(f.read(2), 'little')
print(depth)
#if depth == 24 and int.from_bytes(f.read(4), 'little') == 0:#compress method == uncompressed
if int.from_bytes(f.read(4), 'little') == 3:#compress method == uncompressed
print("Image size:", width, "x", height)
rowsize = (width * 3 + 3) & ~3
if height < 0:
height = -height
flip = False
else:
flip = True
w, h = width, height
if w > 240: w = 240
if h > 135: h = 135
fbuf = framebuf.FrameBuffer(bytearray(f.read()), 198, 120, framebuf.RGB565)
ssd.blit(fbuf, 0, 0)
ssd.show()```
Displaying a picture with a maximum of 16 colors was never going to produce great results. However the framebuf.blit
method has a documented limitation: blitting between buffers created in different modes produces unexpected results. In my view this is a major shortcoming, but discussions on fixing it petered out with no resolution. Until this is fixed you'll have to render pixel by pixel. You'll also need to create a set of 16 colors suitable for the purpose and decide how to map the image's RGB values onto the set of colors you've chosen.
Arguably you're trying to use a screwdriver to install a nail: drawing pictures has nothing to do with nano-gui and your test script uses none of the GUI's features apart from the driver. This is a driver designed for rendering nano-gui widgets and to save RAM by limiting the range of colors to 16. If you don't intend to use features of nano-gui you may find a driver which uses rgb565. Such a driver would be better suited to rendering pictures and would overcome the problems of blitting between incompatible color modes. You might find some help by posting a query in the forum.
Closing as it is out of date. For image display see this doc.
This is not supported by nano-gui. However the drivers are subclassed from FrameBuffer.framebuf, so you can use methods documented here to draw anything you like. Note that some of the drivers (especially the 4-bit ones) support only limited color spaces to conserve RAM, so the rendition of pictures will be poor.