On CPython, a JPEG in an lv.image can't be scaled. set_inner_align(lv.image.ALIGN.CONTAIN) draws a garbled partial crop, and set_scale() draws nothing. On MicroPython the same code scales correctly, because the decoder there is displayif's jpegio. So the same app renders differently on the two.
Repro: a 64×64 Spotify JPEG drawn three ways, with the same script on both interpreters.
img = lv.image(scr)
img.set_src(dsc) # dsc: lv.image_dsc_t, cf RAW, the JPEG bytes
img.set_size(40, 40); img.set_inner_align(lv.image.ALIGN.CONTAIN) # or: img.set_scale(160)
|
native 64 px |
CONTAIN in 40 px |
set_scale(160) |
| MicroPython (jpegio) |
correct |
correct |
correct |
| CPython 9.5.45 (LVGL TJPGD) |
correct |
garbled partial crop |
nothing drawn |
Why
lv_conf.h keeps LV_USE_TJPGD 1 on CPython ("CPython has no jpegio, so LVGL's built-in decoder stays"). LVGL's lv_tjpgd.c decodes tile by tile, and LVGL can't apply a transform to an image that never exists as one whole decoded buffer. jpegio's LVGL decoder decodes the full image in its open step (w * h * 2, freed at close), so zoom and CONTAIN work on MicroPython.
How it showed up
A Spotify remote app draws list-row thumbnails from Spotify's smallest (64 px) image, scaled to 40 px. On MicroPython they look right. On CPython every thumbnail is a mangled crop, so for now the app turns thumbnails off when the decoder isn't jpegio.
Options
- Build jpegio's LVGL decoder (displayif
src/jpegio/lvgl_decoder.c plus its TJpgDec) into the CPython extension in place of LVGL's TJPGD. That gives one decoder with the same behaviour on every target, which is what the lvgl-bindings#14 / displayif#23 note in lv_conf.h is aiming for.
- Or document on the CPython side that JPEG images can't be transformed, so apps know to pick a size that needs no scaling.
On CPython, a JPEG in an
lv.imagecan't be scaled.set_inner_align(lv.image.ALIGN.CONTAIN)draws a garbled partial crop, andset_scale()draws nothing. On MicroPython the same code scales correctly, because the decoder there is displayif's jpegio. So the same app renders differently on the two.Repro: a 64×64 Spotify JPEG drawn three ways, with the same script on both interpreters.
set_scale(160)Why
lv_conf.hkeepsLV_USE_TJPGD 1on CPython ("CPython has no jpegio, so LVGL's built-in decoder stays"). LVGL'slv_tjpgd.cdecodes tile by tile, and LVGL can't apply a transform to an image that never exists as one whole decoded buffer. jpegio's LVGL decoder decodes the full image in its open step (w * h * 2, freed at close), so zoom and CONTAIN work on MicroPython.How it showed up
A Spotify remote app draws list-row thumbnails from Spotify's smallest (64 px) image, scaled to 40 px. On MicroPython they look right. On CPython every thumbnail is a mangled crop, so for now the app turns thumbnails off when the decoder isn't jpegio.
Options
src/jpegio/lvgl_decoder.cplus its TJpgDec) into the CPython extension in place of LVGL's TJPGD. That gives one decoder with the same behaviour on every target, which is what the lvgl-bindings#14 / displayif#23 note inlv_conf.his aiming for.