Repository navigation
Description
Issue draft (espressif/esp-vision — "Firmware" template)
Title: [Firmware] image: PNG accepted at load but decode/save fail ("PNG decoder/encoder is not enabled")
Problem summary
image.Image(path) silently accepts PNG files (header metadata such as width/height
is readable, no error at load), but the first operation that needs pixel decoding
fails with RuntimeError: PNG decoder is not enabled, and saving to a .png path
fails with RuntimeError: PNG encoder is not enabled. This contradicts the
documentation, which lists PNG as a supported format (image.Image.to_png in the
image-model concept page) and states that Image.save() infers the format from the
file extension.
The delayed failure is the harmful part: an app can load a PNG asset at boot without
error and only crash later, mid-stream, when the asset is first used. In our
privacy-camera application, a PNG emoji overlay loaded fine at startup and crashed
the running app (after ~34,000 frames) the moment a face was detected and the
overlay had to be drawn. A load-time rejection (like BMP's) would have caught this
immediately.
Environment
- Board model and hardware revision: ESP32-P4X Function EV Board (ESP32-P4)
- Chip, camera, display, and peripherals: ESP32-P4; camera is not involved in this
repro; no display connected - Firmware version/commit and download source or CI job: esp-vision catalog
firmware, commit3d84b2d(reported by the device firmware check); ESP-IDF
v5.5.6. Latest catalog release 2026.11.06 not yet tested. - ESP-IDF version/commit (custom builds): not applicable (catalog firmware)
- Build command and configuration changes (custom builds): not applicable
- Power supply and connection: USB to host (serial + UVC)
Steps to reproduce
- Flash or boot the firmware above.
- Upload a PNG image to flash (e.g.
/emoji.png, 128x128) and open the REPL. - Run the minimal script:
import image
p = image.Image('/emoji.png') # accepted, no error
p.width() # 128 -> header is read fine
img = image.Image(320, 240, image.RGB565)
img.draw_image(p, 10, 10) # RuntimeError: PNG decoder is not enabled
p.save('/tmp_emoji.png') # RuntimeError: PNG encoder is not enabled
p.save('/tmp_emoji.jpg', quality=80) # OK
j = image.Image('/emoji.jpg') # OK
img.draw_image(j, 10, 10) # OKReproduction frequency: 100% across REPL and running-application contexts, on cold
boot and after soft reset.
Expected behavior
Either of the following:
- PNG assets load, decode, and save as documented ("format inferred from the
extension";to_pnglisted as a supported output), or image.Image(path)rejects a PNG immediately at load with a clear error, like it
does for unsupported BMP data (OSError: Unsupported format!).
Actual behavior
- PNG loads silently (metadata readable), then decode fails later:
RuntimeError: PNG decoder is not enabled. - PNG save fails:
RuntimeError: PNG encoder is not enabled. - JPEG load/decode/save works end to end on the same firmware.
Logs and attachments
emoji.png— PNG asset that loads but fails to decode (any valid PNG reproduces
this; the exact asset is available on request)emoji.jpg— JPEG version of the same asset that works (control case)- No crash log: the failure surfaces as a Python RuntimeError in the REPL and in the
running application.
Workaround and regression
Workaround: convert assets to JPEG before uploading. Unknown whether this worked on
an earlier firmware; first failing version observed is catalog firmware 3d84b2d
(not yet re-tested on 2026.11.06).
Activity