Closed petrkr closed 1 year ago
It would be possible to design a widget that could render arbitrary bitmapped graphics. One approach would be to create a FrameBuffer
instance with the correct dimensions for the graphic, which would be read (typically from a file) and rendered to that FrameBuffer
. The image could then be placed anywhere on the display's buffer using the blit
method.
I have no plans to do this, but would treat any PR on its merits.
Prerequest uqr native library
class QRWidget(Widget):
def __init__(self, writer, row, col, value, scale = 4, border = None):
self._qr = uqr.make(value)
self._border = border or scale * 2
self._scale = scale
self._size = (self._qr.width()*self._scale)+self._border
super().__init__(writer, row, col, self._size, self._size, BLACK, WHITE, WHITE)
self.x = col + self._border // 2
self.y = row + self._border // 2
def show(self):
if not super().show(False): # Draw border, fill background
return
for x in range(self._qr.width()):
for y in range(self._qr.width()):
if self._qr.get(x,y):
display.fill_rect(self.x+x*self._scale, self.y+y*self._scale, self._scale, self._scale, self.fgcolor)
class TestQR(Screen):
def __init__(self):
super().__init__()
wribtn = CWriter(ssd, arial10, WHITE, BLACK)
QRWidget(wribtn, 10, 10, "Test uQR on Micro GUI")
CloseButton(wribtn)
Screen.change(TestQR)
Parse BMP image problem with pixel color.. Because my LCD is not RGB. That is why what should be orange is pink now...
But maybe if I will fill ti framebuffer with framebuf.RGB565 then it could work... But more memory will be needed :(
class BMPWidget(Widget):
def __init__(self, writer, row, col, file):
self._file = open(file, "rb")
magic, size, res1, res2, self._imgoffset = struct.unpack('<2sIHHI', self._file.read(14))
headersize, self._w, self._h, planes, bits, comp, imgdatasize, xres, yres, ncol, icol = struct.unpack('<IiiHHIIiiII', self._file.read(40))
self._rowSize = (self._w * 2 + 2) & ~2
self._fr = self._file.read
self._fs = self._file.seek
super().__init__(writer, row, col, self._h, self._w, None, None, False)
def show(self):
if not super().show(False): # Draw border, fill background
return
dp = ssd.pixel
for row in range(0, self._h):
pos = self._imgoffset + (self._h - 1 - row) * self._rowSize
self._fs(pos)
for col in range(0, self._w):
data = self._fr(2)
dp(col, row, (data[0] << 8) + data[1])
class TestBMP(Screen):
def __init__(self):
super().__init__()
wribtn = CWriter(ssd, arial10, WHITE, BLACK)
BMPWidget(wribtn, 10, 10, "octopuslogo.bmp")
CloseButton(wribtn)
Well... I recognized, library uses 8bit for all three colors (not RGB565 as I thought)... So I did (read found on google) covnert 565 to 888 then used ssd.rgb() to convert to 8bit...
Works, but 3bits per color is really low for some gradient down-scales images, but I think we can work with that, just we will prepare better BMP
def rgb565to8bit(color):
r = ((((color >> 11) & 0x1F) * 527) + 23) >> 6
g = ((((color >> 5) & 0x3F) * 259) + 33) >> 6
b = (((color & 0x1F) * 527) + 23) >> 6
return ssd.rgb(r,g,b)
self._fs(self._imgoffset)
for row in range(0, self._h):
for col in range(0, self._w):
data = self._fr(2)
dp(col, self._h - 1 - row, rgb565to8bit((data[0] << 8) + data[1]))
EDIT: changed bmp read
That looks good.
self._qr = uqr.make(value)
Do you plan to open source the QR code generation? Or is it already out there?
That looks good.
self._qr = uqr.make(value)
Do you plan to open source the QR code generation? Or is it already out there?
It's out, but since developers of uPy says "If you can write it in python, do it in python". Thus they did not embedded this C++ native uQR library to micropython. And that python's version is very slow. You wait up to 3 secods to just generate QR matrix. This C++ native it took less than 100ms.
So I patched uPy and compiled own version... I also thought support that python's version as fallback.
Here is native MPY module https://github.com/coinkite/mpy-qr This is that very slow python's implementation https://github.com/JASchilz/uQR
and Here we talked about that 3 years ago: https://github.com/micropython/micropython/issues/4594 (actually you commented there too)
I think I can close this already, because I was able to do custom components already. Thanks
Is there any way how to window custom graphics such as QR code? I know I can do base ssd.pixel() and draw it over everything, but I feel it is not concept right. So I wonder if I can use some object where I can draw QR and use it as windows/widget/anything