Skip to content

cnadler86/mp_jpeg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MicroPython JPEG

A very fast and memory-efficient micropython jpeg decoder and encoder. At the moment only the esp port is supported.

If you are not familiar with building custom firmware, visit the releases page to download firmware that suits your board!

Decoder

API Reference

  • Decoder(format="RGB888", rotation=0, block=False): Creates a new decoder object.

    • pixel_format: Pixel format for output (RGB565_BE, RGB565_LE, CbYCrY, RGB888).
    • rotation: Rotation angle for decoding (0, 90, 180, 270). Default 0.
    • block: Enable block decoding (default: False). Each time decode is called, it outputs 8 or 16 line data depending on the image and output format (see get_block_counts). If enabled, scale, clipper and rotation are not supported.
    • scale_width and scale_height: Resize the output image to the prvided scale. Note: the scale needs to be consistent with the input image and be a multiple of 8.
    • clipper_width and clipper_height: This will cut the output image to the specified width and/or height. The clipper_height and clipper_width require integer multiples of 8. The resolution of clipper should be less or equal than scale.
    • return_bytes: if true, the decoder return a bytes-object, otherwise a memoryview, default is false.
  • get_img_info(jpeg_data): Returns a list containing the width and height. If the decoder was constructed with block enabled, then it will also return the number of blocks that the decoder will need to decode the full image and the heigh of each block (eihter 8 or 16).

    • jpeg_data: JPEG data to decode.
  • decode(jpeg_data): Decodes the JPEG image and returns the decoded image. With block==True, it decodes the next block of the JPEG image and returns the decoded block. The decoder will give you a block of full width and the height will be either 8 or 16 pixels. You can get the block height by get_img_info

    • jpeg_data: JPEG data to decode.

Example

import jpeg

# Create a JPEG decoder object
decoder = jpeg.Decoder(rotation=180, pixel_format="RGB888")

# Prepare the JPEG data for decoding
jpeg_data = open("path/to/jpeg/image.jpg", "rb").read()

# Decode the JPEG image
decoded_image = decoder.decode(jpeg_data)

Encoder

API Reference

  • Encoder(height=240, width=320, format="RGB888", quality=90, rotation=0): Creates a new encoder object.

    • height: Height of the input image. Required.
    • width: Width of the input image. Required.
    • pixel_format: Pixel format for input image (RGB888, RGBA, YCbYCr, YCbY2YCrY2, GRAY). Required.
    • quality: JPEG quality (1-100). Default 90.
    • rotation: Rotation angle for encoding (0, 90, 180, 270). Default 0.
  • encode(img_data): Encodes the image data to JPEG format and returns the encoded JPEG data.

    • img_data: Raw image data to encode.
    • Returns the bytes of the encoded image.

Example

import jpeg

# Create a JPEG encoder object
encoder = jpeg.Encoder(pixel_format="RGB888", quality=80, rotation=90, width=320, height=240)

# Encode the image data to JPEG format
image_data = open("path/to/raw/image.bin", "rb").read()
encoded_jpeg = encoder.encode(image_data)

Benchmark Results for ESP32S3

The following tables present the results of the JPEG decoding and encoding benchmarks performed on an ESP32S3. The image was 240x320.

Decoder Benchmark

Input Image Size: 26,366 bytes.

Format FPS Normal Decode FPS Block Decode (15)
RGB565_BE 21.80 34.73
RGB565_LE 21.79 34.72
RGB888 17.61 32.14
CbYCrY 21.85 38.17

Input Image Size: 7,941 bytes

Format FPS Normal Decode FPS Block Decode (15)
RGB565_BE 29.65 62.27
RGB565_LE 29.66 62.27
RGB888 22.45 55.74
CbYCrY 29.75 74.57

Block decode will be faster, because other RAM-type might be used.

Encoder Benchmark

Quality FPS RGB888
100 11.90
90 17.58
80 19.62
70 20.55
60 21.35

The FPS might vary, depending on the image.

Build the project

Setting up the build environment

To build the project, follow these instructions:

  • ESP-IDF: I tested it on version 5.2, 5.3 and 5.4, but it might work with other versions.
  • Clone the micropython repo and this repo in a folder, e.g. "MyJPEG". I used MicroPython version 1.24 but might work also with older versions.
  • You will have to add the ESP JPEG library (I used v0.6.0). To do this, add the following to the dependencies in the respective idf_component.yml file (e.g. in micropython/ports/esp32/main_esp32s3/idf_component.yml):
espressif/esp_new_jpeg: "~0.6.1"

Alternatively, you can download the library from the espressif component registry and unzip the data inside the esp-idf/components folder instead of altering the idf_component.yml file. In this case you might need to rename the folder to "esp_new_jpeg".

Build the user module

To build the project, you could do it the following way:

. <path2esp-idf>/esp-idf/export.sh
cd MyJPEG/micropython/ports/esp32
make USER_C_MODULES=../../../../mp_jpeg/src/micropython.cmake BOARD=<Your-Board> clean
make USER_C_MODULES=../../../../mp_jpeg/src/micropython.cmake BOARD=<Your-Board> submodules
make USER_C_MODULES=../../../../mp_jpeg/src/micropython.cmake BOARD=<Your-Board> all

Micropython and mp_jpeg folders are at the same level. Note that you need those extra "/../"s while been inside the esp32 port folder. If you experience problems, visit MicroPython external C modules.

About

A very fast micropython jpeg encoder and decoder for the esp32, with precompiled firmware.

Topics

Resources

License

Stars

Watchers

Forks

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy