Skip to main content

image-rs

Work in progress: this project is not feature complete yet. The API may still change between releases.

Not affiliated with the image-rs organization on GitHub. This is a third party wrapper that makes the awesome Rust image crate available in the Python ecosystem.

image-rs is a thin wrapper around the image crate. It decodes images straight into NumPy arrays and encodes NumPy arrays back into image bytes.

Installation

pip install image-rs

or with uv:

uv add image-rs         # add it as a dependency to your project
uv pip install image-rs # or install it into the current environment

The package requires Python 3.12 or newer and depends on NumPy.

Prebuilt wheels are only available for Linux x86_64 (manylinux2014, CPython 3.12–3.15). On every other platform pip builds the package from the source distribution, which requires a Rust toolchain in version 1.85 or newer (the crate uses the Rust 2024 edition).

Usage

from pathlib import Path

import image_rs

# Decode a JPEG into a (height, width, 3) uint8 NumPy array.
image = image_rs.decode_uint8_image(
    Path("image.jpg").read_bytes(), image_rs.ImageFormat.JPEG, num_channels=3
)
print(image.shape, image.dtype)

# Encode it again as JPEG ...
jpeg_bytes = image_rs.encode_uint8_image(image, image_rs.EncodingOptions.Jpeg(quality=90))

# ... or as PNG with the fastest compression settings.
png_bytes = image_rs.encode_uint8_image(
    image,
    image_rs.EncodingOptions.Png(
        compression=image_rs.PngCompression.FAST,
        filter=image_rs.PngFilter.NO_FILTER,
    ),
)
Path("image.png").write_bytes(png_bytes)

Besides decode_uint8_image there are decode_uint16_image and decode_float32_image (values between 0 and 1) for PNG images, and encode_uint16_image for 16 bit PNG encoding. The encoding functions release the GIL while they run.

For the full interface with docstrings see the type stub image_rs.pyi, which also ships with the package so type checkers and IDEs pick it up. More examples live in the examples directory.

Currently supported functionality

  • Image decoding
    • PNG (uint8, uint16, float32)
    • JPEG (uint8)
    • All other formats supported by the image crate
  • Image encoding
    • PNG (uint8, uint16)
    • JPEG (uint8)
    • All other formats supported by the image crate

Benchmark results

To run the benchmark scripts yourself, run steward sync --include-examples after the development setup to get the needed dependencies.

The presented results were measured on a PC with an AMD 9800x3d, using a build with the dist profile like the wheels created by steward build. They were recorded with an earlier release on Python 3.10, before the minimum supported version was raised to 3.12, so treat them as a rough comparison rather than exact numbers.

Decoding (benchmark.py)

3 channel uint8 JPEG decoding
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.037s, total_time=3.656s, num_passes=100
OpenCV: time_per_pass=0.034s, total_time=3.440s, num_passes=100
torchvision: time_per_pass=0.031s, total_time=3.076s, num_passes=100
pywuffs: time_per_pass=0.059s, total_time=5.947s, num_passes=100
Pillow: time_per_pass=0.052s, total_time=5.165s, num_passes=100

3 channel uint8 PNG decoding
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.056s, total_time=5.631s, num_passes=100
OpenCV: time_per_pass=0.096s, total_time=9.577s, num_passes=100
torchvision: time_per_pass=0.128s, total_time=12.760s, num_passes=100
pywuffs: time_per_pass=0.094s, total_time=9.424s, num_passes=100
Pillow: time_per_pass=0.113s, total_time=11.290s, num_passes=100

3 channel uint16 PNG decoding
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.090s, total_time=8.975s, num_passes=100
OpenCV: time_per_pass=0.172s, total_time=17.218s, num_passes=100
torchvision: time_per_pass=0.212s, total_time=21.189s, num_passes=100

Encoding (encoding_benchmark.py)

3 channel uint8 JPEG encoding (quality 90)
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.177s, total_time=0.887s, num_passes=5, encoded_size=3660KiB
OpenCV: time_per_pass=0.022s, total_time=0.109s, num_passes=5, encoded_size=3427KiB
torchvision: time_per_pass=0.022s, total_time=0.108s, num_passes=5, encoded_size=3433KiB
Pillow: time_per_pass=0.027s, total_time=0.135s, num_passes=5, encoded_size=3433KiB

3 channel uint8 PNG encoding (balanced compression, zlib level 6)
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.572s, total_time=2.858s, num_passes=5, encoded_size=15505KiB
OpenCV: time_per_pass=0.724s, total_time=3.621s, num_passes=5, encoded_size=15507KiB
torchvision: time_per_pass=2.129s, total_time=10.646s, num_passes=5, encoded_size=16266KiB
Pillow: time_per_pass=0.786s, total_time=3.931s, num_passes=5, encoded_size=15442KiB

3 channel uint8 PNG encoding (fastest compression, image_rs FAST vs. zlib level 1)
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.053s, total_time=0.263s, num_passes=5, encoded_size=21709KiB
OpenCV: time_per_pass=0.282s, total_time=1.408s, num_passes=5, encoded_size=22495KiB
torchvision: time_per_pass=0.443s, total_time=2.216s, num_passes=5, encoded_size=16411KiB
Pillow: time_per_pass=0.346s, total_time=1.731s, num_passes=5, encoded_size=22354KiB

3 channel uint8 PNG encoding (fastest compression, image_rs FAST and no filter vs. zlib level 1)
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.042s, total_time=0.210s, num_passes=5, encoded_size=36726KiB
OpenCV: time_per_pass=0.282s, total_time=1.408s, num_passes=5, encoded_size=22495KiB

3 channel uint16 PNG encoding (balanced compression, zlib level 6)
--------------------------------------------------------------------------------
image_rs: time_per_pass=1.433s, total_time=7.167s, num_passes=5, encoded_size=17304KiB
OpenCV: time_per_pass=1.692s, total_time=8.458s, num_passes=5, encoded_size=17327KiB

3 channel uint16 PNG encoding (fastest compression, image_rs FAST vs. zlib level 1)
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.117s, total_time=0.586s, num_passes=5, encoded_size=42940KiB
OpenCV: time_per_pass=0.445s, total_time=2.225s, num_passes=5, encoded_size=31323KiB

3 channel uint16 PNG encoding (fastest compression, image_rs FAST and no filter vs. zlib level 1)
--------------------------------------------------------------------------------
image_rs: time_per_pass=0.098s, total_time=0.490s, num_passes=5, encoded_size=73449KiB
OpenCV: time_per_pass=0.443s, total_time=2.216s, num_passes=5, encoded_size=31323KiB

Development setup

The project depends on the following tools that need to be present in the development environment: git, cargo, rustc, rustfmt, clippy, docker and uv.

Everything else will be installed with a ./steward.py sync. After this first sync call the steward command is also everywhere available in the venv.

Other notable steward commands:

  • steward build local: good for a quick local build of wheels. The wheels are bound to the glibc version of the local system, so use steward build docker for wheels that should run on other machines.
  • steward build docker: by default builds wheels for all currently supported python targets in a manylinux2014 environment.
  • steward lint: runs autoformatting and linting for the whole project.
  • steward prepare-publish: removes dist/, builds all wheels and the sdist with steward build docker and checks them with twine check. The result in dist/ is ready for the upload to PyPI.

The tests run with uv run pytest. The project is installed in editable mode, and uv run rebuilds the Rust extension first whenever a file in src/ changed.

Metadata

Release files for image-rs 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for image-rs 0.2.1
File Size Uploaded
image_rs-0.2.1.tar.gz 13.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for image-rs 0.2.1
File
image_rs-0.2.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.15 CPython 3.15 Linux glibc 2.17+ x86-64 Details
image_rs-0.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ x86-64 Details
image_rs-0.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-64 Details
image_rs-0.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details

Total release size: 2.2 MB

Release files / image_rs-0.2.1.tar.gz

Download URL image_rs-0.2.1.tar.gz
Size 13.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ab5c01d9d20979c9c91762c571e8b07d67f3ad17bf39197be522bf2f9cbd552b
BLAKE2b-256 checksum
How to use checksums
815656ad5eae7c35c18cdc67c57da9293189dfdcb3947efc19f706cb1ff03e28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / image_rs-0.2.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL image_rs-0.2.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 549.4 kB
Tags CPython 3.15 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
83ecd0dc98c4c9647223d7d724436374e4d9a2883c4ef95c3edc523c9ec73c78
BLAKE2b-256 checksum
How to use checksums
d8157407844d203d74dcc678fad59e000f07ed3a55e67f9632613fa070fe36b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / image_rs-0.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL image_rs-0.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 549.6 kB
Tags CPython 3.14 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
e785850c64219fb40dd177e75e32c68dd20d586bac9a74f129a30fb04509adc5
BLAKE2b-256 checksum
How to use checksums
aa14a9eeb761324bcfaabbad40a2e276c5cb75541dc7305c012069fcbb41477c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / image_rs-0.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL image_rs-0.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 549.7 kB
Tags CPython 3.13 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
067be7325e610e28427cf398dd6a864c52867d9ea1716f0a7613a7e8783720f3
BLAKE2b-256 checksum
How to use checksums
cf57427be1199457728e4b74db87a3b44f0ab92cfeb71979a5f85436e39f14cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / image_rs-0.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL image_rs-0.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 549.5 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
bb63e240b87b08eed7290720ff56a90363caea8019ebf4b9cad0317802ff5a9d
BLAKE2b-256 checksum
How to use checksums
ad4a1d289e749af0ded3c51333352392e6e2b674411021031f74199bbf8985c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.2.1 This release

5 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page