{"id":25855398,"url":"https://github.com/cnadler86/mp_jpeg","last_synced_at":"2026-05-09T07:37:17.040Z","repository":{"id":278312150,"uuid":"935197469","full_name":"cnadler86/mp_jpeg","owner":"cnadler86","description":"A very fast micropython jpeg encoder and decoder for the esp32, with precompiled firmware.","archived":false,"fork":false,"pushed_at":"2025-12-13T09:27:35.000Z","size":81,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-14T23:33:57.827Z","etag":null,"topics":["esp32","jpeg","jpeg-decoder","jpeg-encoder","jpg","micropython"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cnadler86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-19T04:02:20.000Z","updated_at":"2025-12-13T09:13:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"98c41907-e6ab-4dda-9cdf-d76f22043a06","html_url":"https://github.com/cnadler86/mp_jpeg","commit_stats":null,"previous_names":["cnadler86/mp_jpeg"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/cnadler86/mp_jpeg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmp_jpeg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmp_jpeg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmp_jpeg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmp_jpeg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cnadler86","download_url":"https://codeload.github.com/cnadler86/mp_jpeg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnadler86%2Fmp_jpeg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32811655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["esp32","jpeg","jpeg-decoder","jpeg-encoder","jpg","micropython"],"created_at":"2025-03-01T17:17:34.228Z","updated_at":"2026-05-09T07:37:17.033Z","avatar_url":"https://github.com/cnadler86.png","language":"C","funding_links":[],"categories":["Libraries"],"sub_categories":["Display"],"readme":"# MicroPython JPEG\n\nA very fast and memory-efficient micropython jpeg decoder and encoder. At the moment only the esp port is supported.\n\nIf you are not familiar with building custom firmware, visit the [releases](https://github.com/cnadler86/mp_jpeg/releases) page to download firmware that suits your board!\n\nTo get the version of the low level driver, you can use the following code:\n\n```python\nimport jpeg\nprint(\"JPEG Driver Version:\", jpeg.version())\n```\n\n## Decoder\n\n### API Reference\n\n- `Decoder(format=\"RGB888\", rotation=0, block=False)`: Creates a new decoder object.\n  - `pixel_format`: Pixel format for output (`RGB565_BE`, `RGB565_LE`, `CbYCrY`, `RGB888`).\n  - `rotation`: Rotation angle for decoding (0, 90, 180, 270). Default 0.\n  - `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.\n  - `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.\n  - `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.\n  - `return_bytes`: if true, the decoder return a bytes-object, otherwise a memoryview, default is false.\n\n- `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). \n  - `jpeg_data`: JPEG data to decode.\n\n- `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`\n  - `jpeg_data`: JPEG data to decode.\n\n### Example\n\n```python\nimport jpeg\n\n# Create a JPEG decoder object\ndecoder = jpeg.Decoder(rotation=180, pixel_format=\"RGB888\")\n\n# Prepare the JPEG data for decoding\njpeg_data = open(\"path/to/jpeg/image.jpg\", \"rb\").read()\n\n# Decode the JPEG image\ndecoded_image = decoder.decode(jpeg_data)\n```\n\n## Encoder\n\n### API Reference\n\n- `Encoder(height=240, width=320, format=\"RGB888\", quality=90, rotation=0)`: Creates a new encoder object.\n  - `height`: Height of the input image. Required.\n  - `width`: Width of the input image. Required.\n  - `pixel_format`: Pixel format for input image (RGB888, RGB565, RGBA, YCbYCr, YCbY2YCrY2, CbYCrY, GRAY). Required.\n  - `quality`: JPEG quality (1-100). Default 90.\n  - `rotation`: Rotation angle for encoding (0, 90, 180, 270). Default 0.\n\n- `encode(img_data)`: Encodes the image data to JPEG format and returns the encoded JPEG data.\n  - `img_data`: Raw image data to encode.\n  - Returns the bytes of the encoded image.\n\n### Example\n\n```python\nimport jpeg\n\n# Create a JPEG encoder object\nencoder = jpeg.Encoder(pixel_format=\"RGB888\", quality=80, rotation=90, width=320, height=240)\n\n# Encode the image data to JPEG format\nimage_data = open(\"path/to/raw/image.bin\", \"rb\").read()\nencoded_jpeg = encoder.encode(image_data)\n```\n\n## Benchmark Results for ESP32S3\n\nThe following tables present the results of the JPEG decoding and encoding benchmarks performed on an ESP32S3. The image was 240x320.\n\n### Decoder Benchmark\n\n**Input Image Size:** 26,366 bytes.\n\n| Format    | FPS Normal Decode | FPS Block Decode (15) |\n|-----------|-------------------|-----------------------|\n| RGB565_BE | 21.80             | 34.73                 |\n| RGB565_LE | 21.79             | 34.72                 |\n| RGB888    | 17.61             | 32.14                 |\n| CbYCrY    | 21.85             | 38.17                 |\n\n**Input Image Size:** 7,941 bytes  \n\n| Format    | FPS Normal Decode | FPS Block Decode (15) |\n|-----------|-------------------|-----------------------|\n| RGB565_BE | 29.65             | 62.27                 |\n| RGB565_LE | 29.66             | 62.27                 |\n| RGB888    | 22.45             | 55.74                 |\n| CbYCrY    | 29.75             | 74.57                 |\n\nBlock decode will be faster, because other RAM-type might be used.\n\n### Encoder Benchmark\n\n| Quality | FPS RGB888 |\n|---------|------------|\n| 100     | 11.90      |\n| 90      | 17.58      |\n| 80      | 19.62      |\n| 70      | 20.55      |\n| 60      | 21.35      |\n\nThe FPS might vary, depending on the image.\n\n### Build the project\n\n### Setting up the build environment\n\nTo build the project, follow these instructions:\n\n- ESP-IDF: I tested it on version 5.2, 5.3 and 5.4, but it might work with other versions.\n- 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.\n- You will have to add the ESP JPEG library (I used v0.6.1). 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):\n\n```yaml\nespressif/esp_new_jpeg: \"^1.0.0\"\n```\n\nAlternatively, you can [download the library from the espressif component registry](https://components.espressif.com/components/espressif/esp_new_jpeg/versions/0.6.1?language=en) 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\".\n\n### Build the user module\n\nTo build the project, you could do it the following way:\n\n```bash\n. \u003cpath2esp-idf\u003e/esp-idf/export.sh\ncd MyJPEG/micropython/ports/esp32\nmake USER_C_MODULES=../../../../mp_jpeg/micropython.cmake BOARD=\u003cYour-Board\u003e clean\nmake USER_C_MODULES=../../../../mp_jpeg/micropython.cmake BOARD=\u003cYour-Board\u003e submodules\nmake USER_C_MODULES=../../../../mp_jpeg/micropython.cmake BOARD=\u003cYour-Board\u003e all\n```\n\nYou can also pass the MP_JPEG_DIR variable to point to the esp_new_jpeg component folder. in ths case you have to build usinf the idf directly.\n\nMicropython 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](https://docs.micropython.org/en/latest/develop/cmodules.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnadler86%2Fmp_jpeg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcnadler86%2Fmp_jpeg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnadler86%2Fmp_jpeg/lists"}