Skip to content

Instantly share code, notes, and snippets.

@amirgon
Last active June 27, 2021 20:41
Show Gist options
  • Save amirgon/4cb0b8320ca98c15544397a72db06b00 to your computer and use it in GitHub Desktop.
Save amirgon/4cb0b8320ca98c15544397a72db06b00 to your computer and use it in GitHub Desktop.
lodepng problem on the simulator
# Initialize
import imp, usys as sys
sys.path.append('https://raw.githubusercontent.com/littlevgl/lv_binding_micropython/dev-8.0/lib')
import display_driver
import lvgl as lv
import ustruct as struct
import lodepng as png
# Load a PNG file
def get_png_info(decoder, src, header):
# Only handle variable image types
if lv.img.src_get_type(src) != lv.img.SRC.VARIABLE:
return lv.RES.INV
png_header = bytes(lv.img_dsc_t.cast(src).data.__dereference__(24))
if png_header.startswith(b'\211PNG\r\n\032\n') and png_header[12:16] == b'IHDR':
try:
width, height = struct.unpack(">LL", png_header[16:24])
except struct.error:
return lv.RES.INV
# Maybe this is for an older PNG version.
elif png_header.startswith(b'\211PNG\r\n\032\n'):
# Check to see if we have the right content type
try:
width, height = struct.unpack(">LL", png_header[8:16])
except struct.error:
return lv.RES.INV
else:
return lv.RES.INV
header.always_zero = 0
header.w = width
header.h = height
header.cf = lv.img.CF.TRUE_COLOR_ALPHA
# print("width=%d, height=%d" % (header.w, header.h))
return lv.RES.OK
# Read and parse PNG file
def open_png(decoder, dsc):
img_dsc = lv.img_dsc_t.cast(dsc.src)
png_data = img_dsc.data
png_size = img_dsc.data_size
png_decoded = png.C_Pointer()
png_width = png.C_Pointer()
png_height = png.C_Pointer()
error = png.decode32(png_decoded, png_width, png_height, png_data, png_size);
if error:
return None # LV_IMG_DECODER_OPEN_FAIL
img_size = png_width.int_val * png_height.int_val * lv.color_t.SIZE
img_data = png_decoded.ptr_val
# Convert png RGBA-big-endian format to lvgl ARGB-little-endian
# Eventually - this means swapping red and blue.
# More info on https://forumtest.littlevgl.com/t/png-decoding-why-red-and-blue-are-swapped/72
img_view = img_data.__dereference__(img_size)
for i in range(0, img_size, lv.color_t.SIZE):
ch = lv.color_t.cast(img_view[i:i]).ch
ch.red, ch.blue = ch.blue, ch.red
dsc.img_data = img_data
return lv.RES.OK
# Register new image decoder
decoder = lv.img.decoder_create()
decoder.info_cb = get_png_info
decoder.open_cb = open_png
# Create a screen with a draggable image
with open('https://raw.githubusercontent.com/littlevgl/lv_binding_micropython/master/examples/png_decoder_test.png','rb') as f:
png_data = f.read()
png_img_dsc = lv.img_dsc_t({
'data_size': len(png_data),
'data': png_data
})
scr = lv.obj()
# Create an image on the left using the decoder
lv.img.cache_set_size(2)
img1 = lv.img(scr)
img1.set_pos(0,50)
img1.set_src(png_img_dsc)
# img1.set_drag(True)
# Create an image on the right directly without the decoder
img2 = lv.img(scr)
img2.set_pos(200,50)
raw_dsc = lv.img_dsc_t()
get_png_info(None, png_img_dsc, raw_dsc.header)
dsc = lv.img_decoder_dsc_t({'src': png_img_dsc})
if open_png(None, dsc) == lv.RES.OK:
raw_dsc.data = dsc.img_data
raw_dsc.data_size = raw_dsc.header.w * raw_dsc.header.h * lv.color_t.SIZE
img2.set_src(raw_dsc)
# img2.set_drag(True)
# Drag handler
def drag_event_handler(e):
self = e.get_target()
indev = lv.indev_get_act()
vect = lv.point_t()
indev.get_vect(vect)
x = self.get_x() + vect.x
y = self.get_y() + vect.y
self.set_pos(x, y)
# Register drag handler for images
for img in [img1, img2]:
img.add_flag(img.FLAG.CLICKABLE)
img.add_event_cb(drag_event_handler, lv.EVENT.PRESSING, None)
# Load the screen and display image
lv.scr_load(scr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment