InfiniTimeOrg / InfiniTime

Firmware for Pinetime smartwatch written in C++ and based on FreeRTOS
GNU General Public License v3.0
2.71k stars 925 forks source link

lv_img_conv.py doesn't handle 8-bit pixel mode #1985

Closed ekirchman closed 8 months ago

ekirchman commented 8 months ago

Verification

Introduce the issue

Pillow supports a lot of different modes as seen here 'P' mode is an 8-bit pixel mode that not only is space efficient but also supports color and transparency. When trying save an an external resource using CF_TRUE_COLOR_ALPHA, the error TypeError: 'int' object is not subscriptable is printed because this mode does not have "channels".

Steps to reproduce:

  1. Follow the official docs for external resources.
  2. Use the following image to generate an lv compatible file: Enemy
  3. See error is reproduced.

A workaround for now is to use Pillow to convert the mode from 'P' to 'RGBA', but this increases the file size.

Full traceback:

Beginning conversion of /home/user/Documents/projects/pinetime/InfiniTime/src/resources/images/FEPT/Enemy.png
overwriting Enemy.bin
Traceback (most recent call last):
  File "/home/user/Documents/projects/pinetime/InfiniTime/src/resources/lv_img_conv.py", line 193, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/user/Documents/projects/pinetime/InfiniTime/src/resources/lv_img_conv.py", line 122, in main
    r_act = classify_pixel(pixel[0], 5)
                           ~~~~~^^^
TypeError: 'int' object is not subscriptable
Traceback (most recent call last):
  File "/home/user/Documents/projects/pinetime/InfiniTime/src/resources/generate-img.py", line 59, in <module>
    main()
  File "/home/user/Documents/projects/pinetime/InfiniTime/src/resources/generate-img.py", line 54, in main
    subprocess.check_call(line)
  File "/usr/lib64/python3.11/subprocess.py", line 413, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/usr/bin/python3.11', '/home/user/Documents/projects/pinetime/InfiniTime/src/resources/lv_img_conv.py', '/home/user/Documents/projects/pinetime/InfiniTime/src/resources/images/FEPT/Enemy.png', '--force', '--output-file', 'Enemy.bin', '--color-format', 'CF_TRUE_COLOR_ALPHA', '--output-format', 'bin', '--binary-format', 'ARGB8565_RBSWAP']' returned non-zero exit status 1.

Preferred solution

Add a condition to check the mode before doing the conversion and handle accordingly

Version

No response

FintasticMan commented 8 months ago

I recently came across a Python script by lvgl for converting images: https://github.com/lvgl/lvgl/blob/master/scripts/LVGLImage.py. Could you see if it works with that?

ekirchman commented 8 months ago

python3 LVGLImage.py --ofmt BIN --cf TRUECOLOR_ALPHA ~/Documents/projects/pinetime/ref/FEPT_imgs/Enemy.png It seemed to work when I made the output format TRUECOLOR_ALPHA.

But it looks like the preferred binary format output for inifiniTime is ARGB8565_RBSWAP. I don't know what binary format this script outputs.

(Uploading the bin file as a zip since Github won't let me upload it as a .bin) Enemy.bin.zip

ekirchman commented 8 months ago

Tagging @NeroBurner