pixtreme
GPU-first image processing for Python, built on CUDA and CuPy.
API reference and documentation — the complete public API (14 modules, 89 operations) with per-function contracts, plus the full performance report.
Why pixtreme
pixtreme keeps image data on the NVIDIA GPU and makes a metadata-bearing Frame the common value passed between
operations. A Frame holds HWC GPU pixels together with colorspace, transfer, channel, and YCbCr-matrix claims,
so color meaning travels with pixels instead of living in ambient configuration.
Frame and px.NDArray provide view() to share pixels with an independent description,
and clone(stream=None) to duplicate pixels. Python copy.copy and copy.deepcopy
also duplicate pixels; use view() when sharing is intended.
Use cupy.from_dlpack(frame) or torch.from_dlpack(frame) to share writable pixels.
DLPack orders the consumer stream after recorded writers and keeps the pixel owner alive.
Read shape and dtype through frame.shape and frame.dtype. To replace the pixel storage,
construct a new px.core.Frame and copy its colorspace, gamma, channels, matrix, range, and bit_depth.
- Purpose-built
RawKernelimplementations and CuPy operations avoid unnecessary host round trips. - Color conversion, format conversion, channel routing, and affine numeric transforms fuse work into a single pass where their contracts allow it.
- Floating-point working values are not clipped to
[0, 1]: negative values, highlights above 1.0, and filter overshoot remain valid scene data until an explicit quantization or clipping boundary. - The package root exposes 14 focused modules, including
core, and__version__. Named tokens match case-insensitively and separator-insensitively (Rec.709,rec 709, andREC_709name the same token; see the token reference), are validated immediately, and have no environment-dependent defaults. Frameis the working currency; device arrays and encoded/file formats cross explicitfrom_*,to_*,read/write, anddecode/encodeboundaries.
Performance
The current package requires CUDA 13, NVIDIA driver R580 or newer, and a GPU with compute capability 7.5 or higher. The table below records the earlier CUDA 12.9 baseline. The DWA and WebP cases of the full performance report were measured separately with CUDA 13.
The following measurements are selected from the original 210-case FHD report, taken from the single full run at
commit 260fe6e. GPU cases use at least 1,000 FHD frames and 3 seconds after warmup, while file boundaries use at
least 20 iterations and the same 3-second floor. The test system used an NVIDIA RTX A6000, CUDA 12.9, CuPy 14.1.1, and
Python 3.12 under WSL2.
The current packed-pixel API uses PixelBuffer conversions.
See the performance report for its measurements. The from_tensor row below
uses the native tensor comparison on CUDA 13.2 instead of the earlier baseline.
| Operation | Representative parameters | Median (ms) | FPS | Effective GB/s |
|---|---|---|---|---|
resize |
1920x1080 -> 960x540, nearest |
0.074 | 13579.6 | 422.4 |
resize |
1920x1080 -> 3840x2160, lanczos4 |
0.980 | 1020.2 | 126.9 |
from_tensor |
CHW uint16, 10-bit -> float32 HWC | 0.122 | 8222.3 | 306.9 |
| YUVA444P packing (legacy API) | 12-bit legal, alpha full | 0.117 | 8563.1 | 426.2 |
rgb_to_rgb |
ACEScg linear -> sRGB sRGB | 0.141 | 7106.3 | 353.7 |
rgb_to_hsv |
label-driven scene values | 0.121 | 8276.1 | 411.9 |
rgb_to_rgb |
BT.2408 direct mapping -> Rec.2020 pq | 0.173 | 5793.1 | 288.3 |
apply_lut |
65^3 LUT, tetrahedral | 0.367 | 2726.8 | 135.7 |
text |
single-line CJK, size 64, one outline, 4x supersampling | 0.401 | 2496.5 | 124.2 |
color_bars |
FHD ARIB STD-B28 normalized | 0.091 | 10969.6 | 273.0 |
read_image |
FHD HALF RGB EXR ZIP, unchanged, temporary-file I/O included | 40.758 | 24.5 | 0.6 |
write_image |
FHD fp32 RGB to EXR ZIP/HALF, dtype omitted, temporary-file I/O included | 40.572 | 24.6 | 0.9 |
These figures describe this system and workload, not a hardware-independent guarantee. File and encoded-byte boundaries have different I/O-inclusive conditions. See the full performance report for every case, distribution statistics, and the complete methodology.
EXR reads support scanline and tiled, single- and multipart files across all ten compression tokens; writes produce
single-part scanline files for the same ten tokens. Every path uses a pixtreme-owned implementation, with no OpenEXR
runtime dependency or fallback. Routing is fixed in source rather than benchmarked at runtime: NONE uses the native
read lane; ZIP, ZIPS, and PXR24 use custom CPU reads; the remaining reads and every write use GPU lanes. A float32
Frame written without dtype stores HALF by default; pass dtype="float32" for explicit FLOAT storage. On the system
above, the default ZIP/HALF path measured 40.758 ms to read unchanged and 40.572 ms to write, including temporary-file
I/O.
Faster WebP decoding in 2.1.0. WebP file reads and decoding from bytes now use pixtreme's C++ and CUDA decoder
(VP8, VP8L, and alpha), writing pixels directly into a GPU Frame. In same-session comparisons with the former
libwebp decode path, RGB and lossless RGBA were about 1.4–1.5 times as fast, and lossy RGBA about 1.1 times as fast.
For FHD (1920×1080) uint8 images on an RTX A6000 with CUDA 13.2 under WSL2, read/decode medians were
22.137/20.515 ms for lossless RGB, 23.300/20.903 ms for lossless RGBA, and 92.719/91.988 ms for lossy RGBA.
File reads include temporary-file I/O; bytes decoding includes host-byte exchange, and both include synchronization
until GPU output is ready. See the WebP performance comparison
for the baseline CPU builds, inputs, and sampling conditions. Still-image I/O supports RGBA with alpha. Malformed
WebP input identified under RFC 6386 or RFC 9649 is rejected with a reason and a remedy. Encoding uses statically
linked libwebp on the CPU and accepts method and quality.
Requirements
- Linux x86_64; Windows users run the Linux package under WSL2
- Python 3.12 or newer
- CUDA 13.x
- NVIDIA driver R580 or newer
- An NVIDIA GPU with compute capability 7.5 or higher
The 2.x wheels target Linux x86_64 (manylinux_2_28) and CPython 3.12 or newer through the stable ABI.
2.x does not provide native Windows wheels. On Windows, use the Linux wheel under WSL2, or use 1.x for native Windows.
Binary wheels need no C++ compiler or CUDA toolkit. Source builds require a C++17 compiler, the CUDA 13 toolkit,
and the zlib headers and shared library. DWA compression uses native CPU workers. DWA reads decode entropy streams
on the CPU and reconstruct dense colour blocks on the supplied CUDA stream. When stream is omitted, they use
the C++ interface's default stream. Subsequent image processing continues on the GPU.
WSL2 is supported with the Windows NVIDIA driver and a working CUDA device. Depending on the WSL installation,
nvidia-smi may be available at /usr/lib/wsl/lib/nvidia-smi rather than on the default PATH.
Installation
With pip:
python -m pip install pixtreme
With uv:
uv add pixtreme
Upgrading from 0.x? The 1.x series is a ground-up rewrite — see the changelog for the migration summary.
Release packages
Download wheels and SHA256SUMS from GitHub Releases.
The C and C++ SDK guide explains how to use the headers,
shared library, and CMake package included in the Linux wheel.
Quickstart
Read an image into GPU memory, work in scene-linear ACEScg, and quantize only at the file boundary:
import pixtreme as px
frame = px.io.read_image("input.png")
working = px.color.rgb_to_rgb(frame, output_colorspace="ACEScg", output_gamma="linear")
working = px.filter.sharpen(working, amount=0.5)
output = px.color.rgb_to_rgb(working, output_colorspace="sRGB", output_gamma="sRGB")
px.io.write_image("output.png", px.values.quantize(output, bit_depth=8))
px.io.read_image returns a px.core.Frame whose pixels already reside on the GPU. Processing remains float32 and
unclipped; px.values.quantize is the explicit normalized-float-to-integer boundary required by PNG.
API tour
The package root exposes the feature modules, Lut1D, Lut3D, NDArray, PixelBuffer, PixelBufferLayout and __version__.
The 89 operations live under their feature modules; the count excludes core, types and query helpers.
Frame has no operation methods.
Packed pixels use px.PixelBuffer, which holds GPU byte storage together with
format, dimensions, plane offsets and pitches, and color declarations. The px.io conversion functions exchange
pixels between a PixelBuffer and a Frame.
| Namespace | Public members | Responsibility |
|---|---|---|
px.core |
Frame, Lut3D, Lut1D, Stream, Event, Graph, capture_begin, capture_end, channels, and the named-token Literal aliases |
Core types, CUDA graph capture, channel normalization, and closed vocabulary |
px.io |
read_image, write_image, write_exr_channels, encode_exr_channels, read_header, read_lut, decode_lut, write_lut, decode_image, encode_image, from_tensor, to_tensor, from_pixel_buffer, to_pixel_buffer, repack_pixel_buffer, read_image_as_pixel_buffer, decode_image_as_pixel_buffer, write_image_from_pixel_buffer, encode_image_from_pixel_buffer |
File, byte, device-array, LUT, and PixelBuffer conversion boundaries |
px.color |
apply_lut, gamma_to_linear, hsv_to_rgb, linear_to_gamma, rgb_to_grayscale, rgb_to_hsv, rgb_to_rgb, rgb_to_ycbcr, ycbcr_to_rgb, ycbcr_to_ycbcr, equalize_histogram, clahe, chromatic_adaptation, white_balance, white_point_simulation, grade |
Colorimetry, transfer functions, YCbCr/HSV, LUTs, histogram operations, white-point adaptation, per-channel Lift / Gamma / Gain, and explicit tonemapping |
px.filter |
gaussian_blur, box_blur, median_blur, bilateral_blur, directional_blur, zoom_blur, spin_blur, vector_blur, lens_blur, sobel, laplacian, difference_of_gaussians, canny, sharpen, unsharp_mask, convolve_box |
Blur, derivatives, edges, sharpening, and convolution |
px.transform |
resize, warp_affine, stack |
Geometry and multi-image layout |
px.draw |
line, polyline, rectangle, circle, ellipse, polygon, text, and the Font type |
Shape and text drawing |
px.generate |
ramp, grid, checkerboard, color_bars, fractal_noise, turbulent_noise, grain |
Procedural frames, test patterns, and noise |
px.morphology |
erosion, dilation, opening, closing, morphological_gradient, white_tophat, black_tophat |
Morphological image operations |
px.metrics |
psnr, ssim, ssim_map, vmaf |
Image and video quality scores and response maps |
px.feature |
corner_harris, match_template |
Image-feature response maps |
px.values |
quantize, dequantize, cast_dtype, recode_dtype |
Pixel-value scale conversion, quantization, and storage representation |
px.channel |
shuffle |
Channel routing and assembly without implicit color meaning changes |
px.composite |
merge |
Transform-aware multi-image compositing |
px.fonts |
font_path, available |
Bundled and installed font-file discovery |
Render the Quickstart's scene-linear working frame through the analytic ACES 2.0 Output Transform:
display = px.color.rgb_to_rgb(
working,
output_colorspace="sRGB",
output_gamma="sRGB",
tonemap="ACES-2.0",
)
The bytes boundary mirrors the file boundary without inventing a host-array API:
png_bytes = px.io.encode_image(
px.values.quantize(display, bit_depth=8),
format="png",
compression_level=4,
)
round_trip = px.io.decode_image(png_bytes)
Text shaping supports bundled CJK fonts, user OpenType/TrueType fonts through px.draw.Font, and an opt-in 4x
supersampled raster path:
captioned = px.draw.text(
display,
text="極彩",
position=(48, 96),
size=64,
color=(1.0, 0.8, 0.2),
supersample=True,
)
Full performance
the full performance report contains the recorded measured cases, including mean, median, FPS, p5, p95, effective bandwidth, parameters, and the 94 cases whose median exceeds 1 ms. It also separates GPU-device throughput from temporary-file and encoded-byte I/O measurements.
Color management
Color processing is explicit, metadata-aware, and designed to preserve scene values until a declared output boundary.
- The closed vocabulary carries 31 colorspace tokens and 37 transfer (gamma) tokens: the sRGB, Rec.709, Rec.2020,
P3, Rec.601-525, Rec.601-625, Adobe RGB, ProPhoto RGB, and ACES families plus the Sony, ARRI, Blackmagic Design, DaVinci, RED, Canon, Panasonic, DJI,
Fujifilm, Nikon, Leica, Apple, and Samsung camera encodings, plus
CIE-XYZandDCDM. Each token is derived from its published specification and documented with its provenance and domain-extension rules in the token reference. - The analytic ACES 2.0 SDR 100-nit Output Transform evaluates the complete AP1 limit, Hellwig JMh, tone, chroma,
gamut-compression, limiting-RGB, reference-range, and display-encoding chain in one fused CUDA pass. Its 363-record
hue table is an algorithm parameter, not an RGB-grid output approximation; runtime evaluation uses no LUT
interpolation and matches direct OpenColorIO 2.5.2 reference evaluation with
rtol=0,atol=2e-4. - ACES 1.3 is also available as a formula-based one-pass transform. Both ACES generations are exposed only through their analytic tonemap tokens.
- BT.2408 direct mapping places SDR reference white at 203 cd/m2 for Rec.2020 HLG or PQ output.
- RGB/YCbCr conversion, legal/full-range code positions, and chroma siting follow H.273-aligned contracts, with the
matrix basis carried in
Framemetadata. - Broadcast test-pattern generation covers ARIB STD-B28, SMPTE RP 219-1, and ITU-R BT.2111-2 HLG/PQ variants, including exact 10-bit code output.
Status & license
The 2.x series is under development, with native C++ support behind the existing Python API. The 1.x series remains the current release line and continues to receive fixes for native Windows users. The 1.x implementation is a ground-up rewrite and does not connect to the 0.x codebase. The final 0.x release remains available as pixtreme 0.9.0 on PyPI. See the changelog for the 1.0 migration-impact summary.
pixtreme is released under the MIT License. JPEG decoding includes libjpeg-turbo components under the IJG License. This software is based in part on the work of the Independent JPEG Group. The wheel includes the complete third-party license texts in its distribution metadata.
Metadata
Release files for pixtreme 2.14.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pixtreme-2.14.0-cp312-abi3-manylinux_2_28_x86_64.whl | CPython 3.12 | abi3 | Linux glibc 2.28+ x86-64 | Details for pixtreme-2.14.0-cp312-abi3-manylinux_2_28_x86_64.whl |
Release files / pixtreme-2.14.0-cp312-abi3-manylinux_2_28_x86_64.whl
| Download URL | pixtreme-2.14.0-cp312-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 71.2 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
6478a0d512d22002911fe3a9899c4d93a2b4eaaed5962ffca9307c5eb7253603
|
|
BLAKE2b-256 checksum How to use checksums |
8ff893fe379b201850ab120e290100dc270ef6cf1b422329df38bc0c45ea330e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for pixtreme 2.14.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.