Skip to main content

Fastest Python bindings for zero-copy JPEG XL & JPEG encoding/decoding and lossless transcoding (static linked)

Project description

pyjpegxl

PyPI version Python versions CI Status License

Python bindings for JPEG XL and JPEG encoding/decoding, powered by libjxl and libjpeg-turbo. Both libraries are statically linked — no system dependencies required.

Features:

  • JPEG XL + JPEG: Full encode/decode/file I/O for both formats in one package.
  • Lossless Transcoding: Reversibly transcode JPEGs into 20% smaller JXLs, and losslessly reconstruct the exact original JPEG bit-for-bit.
  • NumPy Zero-Copy: Directly encode from and decode to numpy.ndarray without memory duplication.
  • True Concurrency: Releases the Python GIL during heavy encoding/decoding operations, enabling true multi-threading.
  • Async API: First-class async/await support via asyncio.to_thread.
  • Performance: Fastest-in-class multi-threaded encoding and decoding.

Installation

pip install pyjpegxl

(Note: Pre-built wheels are currently only available for select platforms. If a wheel is not available, pip will try to build it from source. You will need a Rust toolchain installed.)

Build from source

Requires Rust toolchain and uv:

git clone https://github.com/twn39/pyjpegxl && cd pyjpegxl
# Install dependencies and build extension in-place
uv sync

Quick Start

Basic Usage (Bytes API)

import pyjpegxl

# Decode
with open("image.jxl", "rb") as f:
    meta, pixels = pyjpegxl.decode(f.read())

print(f"{meta.width}x{meta.height}, channels={meta.num_channels}")

# Encode
jxl_data = pyjpegxl.encode(pixels, width=meta.width, height=meta.height)

# Custom Encode
jxl_data = pyjpegxl.encode(
    pixels, width=meta.width, height=meta.height,
    lossless=True,
    speed=pyjpegxl.EncoderSpeed.Falcon,
)

NumPy Zero-Copy API

Move raw bytes to and from NumPy arrays instantly without Python-level allocations.

import pyjpegxl
import numpy as np

with open("image.jxl", "rb") as f:
    # Decode directly into a NumPy array (H, W, C)
    meta, arr = pyjpegxl.decode_to_numpy(f.read())

print(arr.shape, arr.dtype) # e.g. (1080, 1920, 3), dtype('uint8')

# Encode directly from a C-contiguous NumPy array
jxl_data = pyjpegxl.encode_from_numpy(arr, quality=1.0) # quality=1.0 is default for visually lossless

File I/O API

Read and write JXL files directly — no manual open() needed.

import pyjpegxl

# Read a JXL file to a NumPy array
meta, arr = pyjpegxl.read_to_numpy("image.jxl")
print(arr.shape, arr.dtype)

# Write a NumPy array to a JXL file
pyjpegxl.write_from_numpy("output.jxl", arr, lossless=True)

# Bytes-level file I/O
meta, pixels = pyjpegxl.read("image.jxl")
pyjpegxl.write("output.jxl", pixels, width=meta.width, height=meta.height,
               num_channels=meta.num_color_channels + int(meta.has_alpha))

Async API

Perfect for high-concurrency web servers like FastAPI or Starlette.

import asyncio
import pyjpegxl

async def process_image():
    with open("image.jxl", "rb") as f:
        data = f.read()
        
    # Non-blocking decode
    meta, arr = await pyjpegxl.async_decode_to_numpy(data)
    
    # Non-blocking encode
    out_jxl = await pyjpegxl.async_encode_from_numpy(arr)
    
    return out_jxl

asyncio.run(process_image())

JPEG Quick Start

import pyjpegxl

# Read JPEG → NumPy array
info, arr = pyjpegxl.jpeg_read_to_numpy("photo.jpg")
print(arr.shape)  # (H, W, 3)

# Write NumPy array → JPEG file
pyjpegxl.jpeg_write_from_numpy("output.jpg", arr, quality=95)

# In-memory encode/decode
jpeg_data = pyjpegxl.jpeg_encode_from_numpy(arr, quality=90)
info, decoded = pyjpegxl.jpeg_decode_to_numpy(jpeg_data)

Direct JPEG ↔ JXL Lossless Transcoding

Repack JPEGs into smaller JXL files losslessly without ever decoding pixels, and revert them exactly bit-for-bit!

import pyjpegxl

with open("photo.jpg", "rb") as f:
    jpeg_bytes = f.read()

# Transcode directly (lossless, usually 20% smaller)
jxl_bytes = pyjpegxl.jpeg_to_jxl(jpeg_bytes)

# Reconstruct the exact original JPEG bit-for-bit
restored_jpeg_bytes = pyjpegxl.jxl_to_jpeg(jxl_bytes)
assert jpeg_bytes == restored_jpeg_bytes

# Also available natively for File I/O
pyjpegxl.jpeg_file_to_jxl("photo.jpg", "smaller_version.jxl")
pyjpegxl.jxl_file_to_jpeg("smaller_version.jxl", "restored_photo.jpg")

Concurrency and Performance

pyjpegxl natively releases the Global Interpreter Lock (GIL) and engages ThreadsRunner from libjxl. If you use concurrent.futures.ThreadPoolExecutor or asyncio.gather(), multiple images will encode and decode perfectly in parallel without blocking the main Python thread.

Benchmarks (MacBook M-Series)

Benchmark processing images/test.jpg (decoded to Numpy arrays) among Python JXL wrappers on identical visual quality settings:

Library Decode Time (ms) Peak Python Mem Encode Time (ms) Peak Python Mem
pyjpegxl 36.78 0.0 MB 184.47 0.4 MB
pylibjxl 114.86 0.0 MB 366.54 0.5 MB
pillow-jxl 35.56 11.9 MB 185.22 11.3 MB

pyjpegxl is fundamentally the fastest encoder and decoder, while matching the flawless memory performance of pylibjxl due to its zero-copy IntoPyArray bridging.

API Reference

JXL Bytes API

  • decode(data: bytes) -> tuple[Metadata, bytes]
  • encode(data, width, height, *, lossless=False, quality=1.0, speed=EncoderSpeed.Squirrel, num_channels=4) -> bytes

JXL NumPy API

  • decode_to_numpy(data: bytes) -> tuple[Metadata, np.ndarray]
  • encode_from_numpy(array: np.ndarray, *, lossless=False, quality=1.0, speed=EncoderSpeed.Squirrel) -> bytes

JXL File I/O API

  • read(path) -> tuple[Metadata, bytes]
  • read_to_numpy(path) -> tuple[Metadata, np.ndarray]
  • write(path, data, width, height, **kwargs) -> int
  • write_from_numpy(path, array, **kwargs) -> int

JPEG Bytes API

  • jpeg_decode(data: bytes) -> tuple[JpegInfo, bytes]
  • jpeg_encode(data, width, height, *, quality=95, num_channels=3) -> bytes

JPEG NumPy API

  • jpeg_decode_to_numpy(data: bytes) -> tuple[JpegInfo, np.ndarray]
  • jpeg_encode_from_numpy(array: np.ndarray, *, quality=95) -> bytes

JPEG File I/O API

  • jpeg_read(path) -> tuple[JpegInfo, bytes]
  • jpeg_read_to_numpy(path) -> tuple[JpegInfo, np.ndarray]
  • jpeg_write(path, data, width, height, **kwargs) -> int
  • jpeg_write_from_numpy(path, array, **kwargs) -> int

Transcoding API

  • jpeg_to_jxl(data: bytes) -> bytes
  • jxl_to_jpeg(data: bytes) -> bytes
  • jpeg_file_to_jxl(jpeg_path: str, jxl_path: str) -> int
  • jxl_file_to_jpeg(jxl_path: str, jpeg_path: str) -> int

Async API

All sync functions have async variants prefixed with async_ (JXL) or async_jpeg_ (JPEG).

Types

  • Metadata: JXL image dimensions and channel information.
  • JpegInfo: JPEG image dimensions and channel count.
  • EncoderSpeed: JXL compression effort (LightningTortoise).

License

BSD 3-Clause

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyjpegxl-0.2.2.tar.gz (5.5 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyjpegxl-0.2.2-cp314-cp314-win_amd64.whl (5.4 MB view details)

Uploaded CPython 3.14Windows x86-64

pyjpegxl-0.2.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

pyjpegxl-0.2.2-cp314-cp314-macosx_14_0_arm64.whl (1.9 MB view details)

Uploaded CPython 3.14macOS 14.0+ ARM64

pyjpegxl-0.2.2-cp313-cp313-win_amd64.whl (5.4 MB view details)

Uploaded CPython 3.13Windows x86-64

pyjpegxl-0.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

pyjpegxl-0.2.2-cp313-cp313-macosx_14_0_arm64.whl (1.9 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

pyjpegxl-0.2.2-cp312-cp312-win_amd64.whl (5.4 MB view details)

Uploaded CPython 3.12Windows x86-64

pyjpegxl-0.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

pyjpegxl-0.2.2-cp312-cp312-macosx_14_0_arm64.whl (1.9 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

pyjpegxl-0.2.2-cp311-cp311-win_amd64.whl (5.4 MB view details)

Uploaded CPython 3.11Windows x86-64

pyjpegxl-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

pyjpegxl-0.2.2-cp311-cp311-macosx_14_0_arm64.whl (1.9 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

File details

Details for the file pyjpegxl-0.2.2.tar.gz.

File metadata

  • Download URL: pyjpegxl-0.2.2.tar.gz
  • Upload date:
  • Size: 5.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyjpegxl-0.2.2.tar.gz
Algorithm Hash digest
SHA256 914ad83d1e4d678c086e2f3d34bdbbdfcc6168f55e0f78a9d371cec8130fbdc8
MD5 ed3127f3151d09364509234fbae9a1b7
BLAKE2b-256 8a642bba9ef13977615495b8db53e8234488e873899ee931ca72ac6f535533f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2.tar.gz:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: pyjpegxl-0.2.2-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 5.4 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyjpegxl-0.2.2-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 fc35e45d432a9aaa5c222668ec13f5e1201d7356f10bc25665155b85b2340dbd
MD5 d84036b3db0f46e913da69e4df6aa684
BLAKE2b-256 1d83ee2495c18850e94649e4dec5e859d245cec5dae159db238cfd7824b6fcda

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp314-cp314-win_amd64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1129889bb642265c2e9cfa12ea5a9fb2a4f7193af83ab525db3a0a5d2bfb01b8
MD5 3585eccaa3b7bfbcd3060b9d14dfeca9
BLAKE2b-256 0cb9f0e6ef4586f2ea2a13f27fbdd48eb0f466e04d52815f0faf9707264df54d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp314-cp314-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 6b05878a9ca5bafa2767debcd942a39816923cb4f23f9cf0edb09cd5a21f8280
MD5 2ad03c6cfd6d3be403e8bbf614d5cbc0
BLAKE2b-256 7a248386436f8097b780c334f92725d37cf7b6479356a7b010c62a24bd895440

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp314-cp314-macosx_14_0_arm64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pyjpegxl-0.2.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 5.4 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyjpegxl-0.2.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 93e5699fb24b23d28ce0fd07c07982c5431d2acb9f2d32e6e0e3900f203c29f9
MD5 a2b0acf6a15068754ad937d35928da54
BLAKE2b-256 cbcf7871c9ed762a6678bba0fedc2d9e7915e346fe0789cae2f8a7d14111ee9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp313-cp313-win_amd64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4f587e78134dc90e0520b93cfd9f522f76405b6c5934dfcb12bb7453c56aa7a4
MD5 530624ea5659e57185304e4973666644
BLAKE2b-256 a1a03c9d4ca35ff86d7e31f0a7d9b84421dad107258c580dc5bd96dae5d50fce

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 0261bf10d8140711c1702ee30ef75fc1c81d5dd1a04351e173eccca5cef12554
MD5 8813839817f6e60314e58149d4fef7e1
BLAKE2b-256 065489419683f20d3ad3fa12edfc65dab1b9aabb725b55f25d7fbe0fc1bc30b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp313-cp313-macosx_14_0_arm64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pyjpegxl-0.2.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 5.4 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyjpegxl-0.2.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e5688a5c85c758c7911f4923c7ca6e321c1224a5ca9ba56b63e545155dd43c80
MD5 ba3756c69ea654510e51d7da194979a2
BLAKE2b-256 91ee03f962976af500a5a3448fe93d1b2f7a7d7775cdb76ef441b75e67efd1cf

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp312-cp312-win_amd64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c11ce170bbb61296bd91ba48236ceb36edd766a50e5ae61ed05686f6279b5d20
MD5 a08cd299112e0292375df8cdfe3d855f
BLAKE2b-256 a8367c6ce7e36836cd8978048d77b00f4aedf2210cb850af8dac46177e78bff2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 5278013a8fe1ae4f7852fbc0845dfd45c6e766d12d1628a3669f84eb42ed01ae
MD5 55211e56a1c19b3be9dce9042a103057
BLAKE2b-256 2190f5d9173b0942f4fd0ff6432a4d8c4b9883bd00f5d1a221448c7e22aeef56

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp312-cp312-macosx_14_0_arm64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pyjpegxl-0.2.2-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 5.4 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyjpegxl-0.2.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 bad172863aa88df539a72af70e1456e65a5b51bf4e9015e27ba56ab5e43ead00
MD5 6b93f1067d1fbd60e2a9122c13b2988d
BLAKE2b-256 93aed576304e62cbdd9376715856d25dd655fb29579438bda05236d77d4eb2c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp311-cp311-win_amd64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 34125852a4cb42cbb19e2d1596401db9592ce61ff681d62c3d61df39f61c4f0e
MD5 45136260e7b139b4e780619b58aefecf
BLAKE2b-256 c6c3672aaf5a4976c1ffb1398b8dc0108d4424d7e7788f8f14e27abaaf1a2ed1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjpegxl-0.2.2-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyjpegxl-0.2.2-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 b1fc16fbce1ac952db8bc6ba7ff0652d049e70515c747a42cd1612b7a8a7f1ef
MD5 d84334c7e91c3e3daba86c1312474e8a
BLAKE2b-256 7a08159068ddb99622f25613e7712319530ceff4faeeb2858a8db96b0d6966cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjpegxl-0.2.2-cp311-cp311-macosx_14_0_arm64.whl:

Publisher: ci.yml on twn39/pyjpegxl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page