libstb Documentation
GitHub
libstb benchmark report · generated 2026-10-15 11:30 UTC

libstb, measured honestly

Image decoding, encoding, resizing and text, each measured on its own against the libraries people actually reach for: Pillow, OpenCV, imageio and scikit-image.

88 corpus entries · 7 repeats per cell · 225 output checks passed before timing
Method

How the numbers are computed

Each corpus entry \(i\) is one image (a genre, a size and a format). For a library \(L\), \(t_i^{L}\) is the best of 7 timed runs of one operation on entry \(i\), \(s_i^{L}\) is the size in bytes of the file it wrote, and \(m_i^{L}\) is its extra peak memory. Two libraries are compared only on the entries where both ran.

Install footprint

What pip install pulls in

Download size of the wheel for this platform plus every dependency, resolved from PyPI by pip-size. Capability is not the same thing as size: a bigger package is usually doing far more, which is why the last column is here.

Total download size (lower is better)

PackageVersionTotalDepsWhat it is
libstb ★ 0.5.0 2.1 MB 0 image decode, png/jpg/bmp/tga encode, resize, TrueType text (stb, no system dependencies)
Pillow 12.3.0 6.6 MB 0 many-format image io, resize, filters, drawing, FreeType text
numpy 2.5.4 16.0 MB 0 arrays only (a dependency of OpenCV, imageio and scikit-image; optional for libstb, not used by Pillow)
imageio 2.38.1 22.9 MB 2 many-format image io (delegates to Pillow and friends)
scikit-image 0.26.0 72.0 MB 8 image processing algorithms (io + resize + far more)
OpenCV 5.0.0.93 74.3 MB 1 image io, resize, and a large computer-vision toolkit
Decoding

Reading images

Header-only reads and full decodes, from bytes and from a file, on every corpus entry: synthetic images of four shapes and real photographs, each stored as png, jpg, bmp and tga. Speed is the best of 7 runs; memory is the extra peak RSS of one isolated process per measurement.

info: read the header only, no pixels

Width, height and channel count without decoding anything. Only libstb and Pillow have a header-only call; OpenCV and imageio do not, so they are absent here.

libstb is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{libstb}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): Pillow 6.4× as long.

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

See per-entry detail (88 corpus entries)
gradient/64x64/png
time (lower is better)
libstb 0.009ms · Pillow 0.051ms
gradient/64x64/jpg
time (lower is better)
libstb 0.009ms · Pillow 0.062ms
gradient/64x64/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.047ms
gradient/64x64/tga
time (lower is better)
libstb 0.010ms · Pillow 0.092ms
gradient/256x256/png
time (lower is better)
libstb 0.009ms · Pillow 0.055ms
gradient/256x256/jpg
time (lower is better)
libstb 0.011ms · Pillow 0.065ms
gradient/256x256/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.047ms
gradient/256x256/tga
time (lower is better)
libstb 0.010ms · Pillow 0.095ms
gradient/1024x1024/png
time (lower is better)
libstb 0.011ms · Pillow 0.057ms
gradient/1024x1024/jpg
time (lower is better)
libstb 0.015ms · Pillow 0.085ms
gradient/1024x1024/bmp
time (lower is better)
libstb 0.017ms · Pillow 0.067ms
gradient/1024x1024/tga
time (lower is better)
libstb 0.018ms · Pillow 0.132ms
gradient/2048x2048/png
time (lower is better)
libstb 0.017ms · Pillow 0.081ms
gradient/2048x2048/jpg
time (lower is better)
libstb 0.011ms · Pillow 0.061ms
gradient/2048x2048/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.047ms
gradient/2048x2048/tga
time (lower is better)
libstb 0.011ms · Pillow 0.092ms
photo/64x64/png
time (lower is better)
libstb 0.010ms · Pillow 0.055ms
photo/64x64/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.060ms
photo/64x64/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.046ms
photo/64x64/tga
time (lower is better)
libstb 0.010ms · Pillow 0.099ms
photo/256x256/png
time (lower is better)
libstb 0.010ms · Pillow 0.056ms
photo/256x256/jpg
time (lower is better)
libstb 0.011ms · Pillow 0.061ms
photo/256x256/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.046ms
photo/256x256/tga
time (lower is better)
libstb 0.010ms · Pillow 0.099ms
photo/1024x1024/png
time (lower is better)
libstb 0.010ms · Pillow 0.055ms
photo/1024x1024/jpg
time (lower is better)
libstb 0.011ms · Pillow 0.060ms
photo/1024x1024/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.045ms
photo/1024x1024/tga
time (lower is better)
libstb 0.014ms · Pillow 0.092ms
photo/2048x2048/png
time (lower is better)
libstb 0.010ms · Pillow 0.055ms
photo/2048x2048/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.060ms
photo/2048x2048/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.044ms
photo/2048x2048/tga
time (lower is better)
libstb 0.010ms · Pillow 0.092ms
noise/64x64/png
time (lower is better)
libstb 0.010ms · Pillow 0.055ms
noise/64x64/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.060ms
noise/64x64/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.044ms
noise/64x64/tga
time (lower is better)
libstb 0.010ms · Pillow 0.095ms
noise/256x256/png
time (lower is better)
libstb 0.009ms · Pillow 0.055ms
noise/256x256/jpg
time (lower is better)
libstb 0.011ms · Pillow 0.059ms
noise/256x256/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.045ms
noise/256x256/tga
time (lower is better)
libstb 0.011ms · Pillow 0.090ms
noise/1024x1024/png
time (lower is better)
libstb 0.010ms · Pillow 0.054ms
noise/1024x1024/jpg
time (lower is better)
libstb 0.011ms · Pillow 0.063ms
noise/1024x1024/bmp
time (lower is better)
libstb 0.011ms · Pillow 0.050ms
noise/1024x1024/tga
time (lower is better)
libstb 0.010ms · Pillow 0.091ms
noise/2048x2048/png
time (lower is better)
libstb 0.010ms · Pillow 0.060ms
noise/2048x2048/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.063ms
noise/2048x2048/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.046ms
noise/2048x2048/tga
time (lower is better)
libstb 0.010ms · Pillow 0.098ms
graphics/64x64/png
time (lower is better)
libstb 0.010ms · Pillow 0.055ms
graphics/64x64/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.062ms
graphics/64x64/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.045ms
graphics/64x64/tga
time (lower is better)
libstb 0.011ms · Pillow 0.094ms
graphics/256x256/png
time (lower is better)
libstb 0.010ms · Pillow 0.054ms
graphics/256x256/jpg
time (lower is better)
libstb 0.012ms · Pillow 0.061ms
graphics/256x256/bmp
time (lower is better)
libstb 0.011ms · Pillow 0.046ms
graphics/256x256/tga
time (lower is better)
libstb 0.010ms · Pillow 0.092ms
graphics/1024x1024/png
time (lower is better)
libstb 0.010ms · Pillow 0.056ms
graphics/1024x1024/jpg
time (lower is better)
libstb 0.009ms · Pillow 0.063ms
graphics/1024x1024/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.047ms
graphics/1024x1024/tga
time (lower is better)
libstb 0.010ms · Pillow 0.094ms
graphics/2048x2048/png
time (lower is better)
libstb 0.011ms · Pillow 0.054ms
graphics/2048x2048/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.060ms
graphics/2048x2048/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.046ms
graphics/2048x2048/tga
time (lower is better)
libstb 0.011ms · Pillow 0.093ms
real-baboon/512x512/png
time (lower is better)
libstb 0.011ms · Pillow 0.055ms
real-baboon/512x512/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.060ms
real-baboon/512x512/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.047ms
real-baboon/512x512/tga
time (lower is better)
libstb 0.010ms · Pillow 0.102ms
real-butterfly/493x356/png
time (lower is better)
libstb 0.010ms · Pillow 0.055ms
real-butterfly/493x356/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.066ms
real-butterfly/493x356/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.046ms
real-butterfly/493x356/tga
time (lower is better)
libstb 0.010ms · Pillow 0.102ms
real-fruits/512x480/png
time (lower is better)
libstb 0.010ms · Pillow 0.059ms
real-fruits/512x480/jpg
time (lower is better)
libstb 0.009ms · Pillow 0.060ms
real-fruits/512x480/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.078ms
real-fruits/512x480/tga
time (lower is better)
libstb 0.010ms · Pillow 0.124ms
real-home/512x384/png
time (lower is better)
libstb 0.014ms · Pillow 0.077ms
real-home/512x384/jpg
time (lower is better)
libstb 0.010ms · Pillow 0.063ms
real-home/512x384/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.045ms
real-home/512x384/tga
time (lower is better)
libstb 0.010ms · Pillow 0.092ms
real-lena/512x512/png
time (lower is better)
libstb 0.010ms · Pillow 0.054ms
real-lena/512x512/jpg
time (lower is better)
libstb 0.009ms · Pillow 0.058ms
real-lena/512x512/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.045ms
real-lena/512x512/tga
time (lower is better)
libstb 0.010ms · Pillow 0.091ms
real-messi5/548x342/png
time (lower is better)
libstb 0.009ms · Pillow 0.053ms
real-messi5/548x342/jpg
time (lower is better)
libstb 0.009ms · Pillow 0.060ms
real-messi5/548x342/bmp
time (lower is better)
libstb 0.010ms · Pillow 0.045ms
real-messi5/548x342/tga
time (lower is better)
libstb 0.010ms · Pillow 0.093ms

decode: encoded bytes in, pixel array out

Each file was written by Pillow, never by stb. OpenCV has no TGA decoder, so it has no TGA entries. imageio delegates to Pillow, so it is Pillow plus its own overhead.

libstb is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{libstb}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): OpenCV 0.9×, Pillow 2.0×, imageio 3.3× as long.

libstb needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{libstb}}}\right]\): OpenCV 4.2×, Pillow 5.1×, imageio 6.5× as much.

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (88 corpus entries)
gradient/64x64/png
time (lower is better)
libstb 0.089ms · OpenCV 0.121ms · Pillow 0.205ms · imageio 0.330ms
gradient/64x64/jpg
time (lower is better)
libstb 0.052ms · OpenCV 0.058ms · Pillow 0.141ms · imageio 0.279ms
gradient/64x64/bmp
time (lower is better)
OpenCV 0.017ms · libstb 0.029ms · Pillow 0.089ms · imageio 0.214ms
gradient/64x64/tga
time (lower is better)
libstb 0.021ms · Pillow 0.138ms · imageio 0.276ms
gradient/256x256/png
time (lower is better)
libstb 0.743ms · OpenCV 0.996ms · Pillow 1.22ms · imageio 1.36ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
gradient/256x256/jpg
time (lower is better)
OpenCV 0.224ms · libstb 0.311ms · Pillow 0.502ms · imageio 0.627ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB · imageio 0.0MB
gradient/256x256/bmp
time (lower is better)
OpenCV 0.035ms · Pillow 0.175ms · libstb 0.178ms · imageio 0.300ms
gradient/256x256/tga
time (lower is better)
libstb 0.057ms · Pillow 0.237ms · imageio 0.346ms
gradient/1024x1024/png
time (lower is better)
libstb 11.2ms · OpenCV 14.9ms · Pillow 17.4ms · imageio 20.5ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 2.4MB · OpenCV 3.6MB
gradient/1024x1024/jpg
time (lower is better)
OpenCV 2.21ms · libstb 3.55ms · Pillow 3.97ms · imageio 4.37ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 2.5MB · OpenCV 3.1MB
gradient/1024x1024/bmp
time (lower is better)
OpenCV 0.582ms · Pillow 1.77ms · imageio 2.20ms · libstb 2.62ms
gradient/1024x1024/tga
time (lower is better)
libstb 0.908ms · Pillow 1.85ms · imageio 2.30ms
gradient/2048x2048/png
time (lower is better)
libstb 40.8ms · OpenCV 49.2ms · Pillow 59.1ms · imageio 69.8ms
extra peak memory (lower is better)
libstb 11.6MB · OpenCV 22.6MB · Pillow 26.6MB · imageio 29.9MB
gradient/2048x2048/jpg
time (lower is better)
OpenCV 7.59ms · Pillow 11.7ms · libstb 13.6ms · imageio 21.5ms
extra peak memory (lower is better)
libstb 2.8MB · OpenCV 21.2MB · Pillow 25.9MB · imageio 29.4MB
gradient/2048x2048/bmp
time (lower is better)
OpenCV 1.72ms · Pillow 6.12ms · libstb 10.3ms · imageio 15.4ms
gradient/2048x2048/tga
time (lower is better)
libstb 2.44ms · Pillow 6.12ms · imageio 15.6ms
photo/64x64/png
time (lower is better)
libstb 0.113ms · OpenCV 0.143ms · Pillow 0.232ms · imageio 0.363ms
photo/64x64/jpg
time (lower is better)
libstb 0.054ms · OpenCV 0.061ms · Pillow 0.132ms · imageio 0.256ms
photo/64x64/bmp
time (lower is better)
OpenCV 0.017ms · libstb 0.030ms · Pillow 0.090ms · imageio 0.216ms
photo/64x64/tga
time (lower is better)
libstb 0.021ms · Pillow 0.140ms · imageio 0.265ms
photo/256x256/png
time (lower is better)
libstb 0.739ms · OpenCV 1.04ms · Pillow 1.22ms · imageio 1.33ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
photo/256x256/jpg
time (lower is better)
OpenCV 0.260ms · libstb 0.332ms · Pillow 0.444ms · imageio 0.586ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB · imageio 0.0MB
photo/256x256/bmp
time (lower is better)
OpenCV 0.038ms · Pillow 0.179ms · libstb 0.180ms · imageio 0.321ms
photo/256x256/tga
time (lower is better)
libstb 0.056ms · Pillow 0.226ms · imageio 0.373ms
photo/1024x1024/png
time (lower is better)
libstb 8.52ms · OpenCV 12.4ms · Pillow 13.5ms · imageio 13.9ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 2.9MB · OpenCV 4.2MB
photo/1024x1024/jpg
time (lower is better)
OpenCV 2.63ms · Pillow 3.63ms · imageio 4.01ms · libstb 4.20ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 2.5MB · OpenCV 3.2MB
photo/1024x1024/bmp
time (lower is better)
OpenCV 0.438ms · Pillow 1.59ms · imageio 1.94ms · libstb 2.57ms
photo/1024x1024/tga
time (lower is better)
libstb 0.648ms · Pillow 1.59ms · imageio 1.97ms
photo/2048x2048/png
time (lower is better)
libstb 23.4ms · OpenCV 37.5ms · Pillow 41.7ms · imageio 53.8ms
extra peak memory (lower is better)
libstb 14.5MB · OpenCV 24.1MB · Pillow 28.3MB · imageio 31.8MB
photo/2048x2048/jpg
time (lower is better)
OpenCV 8.30ms · Pillow 12.5ms · libstb 15.0ms · imageio 21.7ms
extra peak memory (lower is better)
libstb 2.9MB · OpenCV 21.3MB · Pillow 26.1MB · imageio 41.3MB
photo/2048x2048/bmp
time (lower is better)
OpenCV 1.73ms · Pillow 6.05ms · libstb 10.3ms · imageio 15.6ms
photo/2048x2048/tga
time (lower is better)
libstb 2.55ms · Pillow 6.12ms · imageio 15.2ms
noise/64x64/png
time (lower is better)
libstb 0.033ms · OpenCV 0.052ms · Pillow 0.127ms · imageio 0.252ms
noise/64x64/jpg
time (lower is better)
libstb 0.078ms · OpenCV 0.079ms · Pillow 0.162ms · imageio 0.289ms
noise/64x64/bmp
time (lower is better)
OpenCV 0.017ms · libstb 0.029ms · Pillow 0.091ms · imageio 0.209ms
noise/64x64/tga
time (lower is better)
libstb 0.021ms · Pillow 0.141ms · imageio 0.264ms
noise/256x256/png
time (lower is better)
libstb 0.749ms · OpenCV 0.979ms · Pillow 1.08ms · imageio 1.21ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
noise/256x256/jpg
time (lower is better)
OpenCV 0.603ms · Pillow 0.668ms · libstb 0.808ms · imageio 0.828ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
noise/256x256/bmp
time (lower is better)
OpenCV 0.035ms · Pillow 0.174ms · libstb 0.176ms · imageio 0.302ms
noise/256x256/tga
time (lower is better)
libstb 0.055ms · Pillow 0.220ms · imageio 0.350ms
noise/1024x1024/png
time (lower is better)
libstb 14.2ms · OpenCV 17.5ms · Pillow 18.2ms · imageio 18.7ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 4.8MB · OpenCV 6.1MB
noise/1024x1024/jpg
time (lower is better)
OpenCV 8.68ms · Pillow 9.78ms · imageio 10.2ms · libstb 11.9ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 3.2MB · OpenCV 3.9MB
noise/1024x1024/bmp
time (lower is better)
OpenCV 0.449ms · Pillow 1.62ms · imageio 1.95ms · libstb 2.61ms
noise/1024x1024/tga
time (lower is better)
libstb 0.656ms · Pillow 1.63ms · imageio 2.00ms
noise/2048x2048/png
time (lower is better)
libstb 42.1ms · OpenCV 53.8ms · Pillow 56.6ms · imageio 67.9ms
extra peak memory (lower is better)
libstb 20.7MB · OpenCV 25.4MB · Pillow 37.2MB · imageio 40.5MB
noise/2048x2048/jpg
time (lower is better)
OpenCV 34.2ms · Pillow 38.5ms · libstb 48.3ms · imageio 49.2ms
extra peak memory (lower is better)
libstb 6.0MB · OpenCV 24.6MB · Pillow 29.2MB · imageio 44.6MB
noise/2048x2048/bmp
time (lower is better)
OpenCV 1.79ms · Pillow 6.15ms · libstb 10.4ms · imageio 16.8ms
noise/2048x2048/tga
time (lower is better)
libstb 2.44ms · Pillow 6.21ms · imageio 16.8ms
graphics/64x64/png
time (lower is better)
libstb 0.041ms · OpenCV 0.064ms · Pillow 0.149ms · imageio 0.283ms
graphics/64x64/jpg
time (lower is better)
libstb 0.073ms · OpenCV 0.076ms · Pillow 0.153ms · imageio 0.289ms
graphics/64x64/bmp
time (lower is better)
OpenCV 0.017ms · libstb 0.030ms · Pillow 0.097ms · imageio 0.222ms
graphics/64x64/tga
time (lower is better)
libstb 0.022ms · Pillow 0.139ms · imageio 0.265ms
graphics/256x256/png
time (lower is better)
libstb 0.101ms · OpenCV 0.383ms · Pillow 0.511ms · imageio 0.666ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
graphics/256x256/jpg
time (lower is better)
OpenCV 0.298ms · libstb 0.387ms · Pillow 0.477ms · imageio 0.607ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB · imageio 0.0MB
graphics/256x256/bmp
time (lower is better)
OpenCV 0.036ms · libstb 0.179ms · Pillow 0.180ms · imageio 0.309ms
graphics/256x256/tga
time (lower is better)
libstb 0.062ms · Pillow 0.208ms · imageio 0.361ms
graphics/1024x1024/png
time (lower is better)
libstb 1.23ms · OpenCV 4.94ms · Pillow 6.09ms · imageio 6.57ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 0.7MB · OpenCV 4.9MB
graphics/1024x1024/jpg
time (lower is better)
OpenCV 2.42ms · Pillow 3.62ms · imageio 3.97ms · libstb 4.25ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 2.3MB · OpenCV 3.1MB
graphics/1024x1024/bmp
time (lower is better)
OpenCV 0.439ms · Pillow 1.57ms · imageio 1.97ms · libstb 2.58ms
graphics/1024x1024/tga
time (lower is better)
libstb 0.712ms · Pillow 1.32ms · imageio 1.75ms
graphics/2048x2048/png
time (lower is better)
libstb 4.06ms · OpenCV 18.7ms · Pillow 22.7ms · imageio 35.4ms
extra peak memory (lower is better)
libstb 16.6MB · OpenCV 29.0MB · Pillow 33.2MB · imageio 36.8MB
graphics/2048x2048/jpg
time (lower is better)
OpenCV 7.82ms · Pillow 11.9ms · libstb 14.7ms · imageio 22.0ms
extra peak memory (lower is better)
libstb 2.8MB · OpenCV 21.4MB · Pillow 26.1MB · imageio 29.4MB
graphics/2048x2048/bmp
time (lower is better)
OpenCV 1.79ms · Pillow 6.21ms · libstb 10.3ms · imageio 15.9ms
graphics/2048x2048/tga
time (lower is better)
libstb 3.02ms · Pillow 5.19ms · imageio 17.5ms
real-baboon/512x512/png
time (lower is better)
libstb 4.93ms · OpenCV 5.90ms · Pillow 6.29ms · imageio 6.58ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-baboon/512x512/jpg
time (lower is better)
OpenCV 1.53ms · Pillow 1.68ms · imageio 1.89ms · libstb 2.19ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-baboon/512x512/bmp
time (lower is better)
OpenCV 0.098ms · Pillow 0.453ms · imageio 0.625ms · libstb 0.661ms
real-baboon/512x512/tga
time (lower is better)
libstb 0.164ms · Pillow 0.506ms · imageio 0.700ms
real-butterfly/493x356/png
time (lower is better)
libstb 3.29ms · OpenCV 3.96ms · Pillow 4.33ms · imageio 4.53ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-butterfly/493x356/jpg
time (lower is better)
OpenCV 0.743ms · Pillow 0.916ms · imageio 1.10ms · libstb 1.30ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-butterfly/493x356/bmp
time (lower is better)
OpenCV 0.070ms · Pillow 0.331ms · libstb 0.442ms · imageio 0.475ms
real-butterfly/493x356/tga
time (lower is better)
libstb 0.116ms · Pillow 0.383ms · imageio 0.523ms
real-fruits/512x480/png
time (lower is better)
libstb 5.17ms · OpenCV 6.24ms · Pillow 7.26ms · imageio 7.38ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-fruits/512x480/jpg
time (lower is better)
OpenCV 0.960ms · Pillow 1.12ms · imageio 1.24ms · libstb 1.41ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-fruits/512x480/bmp
time (lower is better)
OpenCV 0.131ms · Pillow 0.493ms · libstb 0.640ms · imageio 0.675ms
real-fruits/512x480/tga
time (lower is better)
libstb 0.181ms · Pillow 0.550ms · imageio 0.727ms
real-home/512x384/png
time (lower is better)
libstb 3.43ms · OpenCV 4.01ms · Pillow 4.58ms · imageio 4.72ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-home/512x384/jpg
time (lower is better)
OpenCV 0.728ms · Pillow 0.837ms · imageio 1.02ms · libstb 1.14ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-home/512x384/bmp
time (lower is better)
OpenCV 0.076ms · Pillow 0.386ms · imageio 0.500ms · libstb 0.505ms
real-home/512x384/tga
time (lower is better)
libstb 0.125ms · Pillow 0.416ms · imageio 0.557ms
real-lena/512x512/png
time (lower is better)
libstb 5.48ms · OpenCV 6.61ms · Pillow 7.43ms · imageio 7.55ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-lena/512x512/jpg
time (lower is better)
OpenCV 1.09ms · Pillow 1.22ms · imageio 1.36ms · libstb 1.57ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-lena/512x512/bmp
time (lower is better)
OpenCV 0.095ms · Pillow 0.442ms · imageio 0.630ms · libstb 0.670ms
real-lena/512x512/tga
time (lower is better)
libstb 0.162ms · Pillow 0.513ms · imageio 0.672ms
real-messi5/548x342/png
time (lower is better)
libstb 3.50ms · OpenCV 4.33ms · Pillow 4.98ms · imageio 5.06ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-messi5/548x342/jpg
time (lower is better)
OpenCV 0.719ms · Pillow 0.879ms · imageio 1.02ms · libstb 1.14ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-messi5/548x342/bmp
time (lower is better)
OpenCV 0.071ms · Pillow 0.350ms · libstb 0.468ms · imageio 0.492ms
real-messi5/548x342/tga
time (lower is better)
libstb 0.117ms · Pillow 0.388ms · imageio 0.557ms

load_file: path in, pixel array out

The same as decode but starting from a path, so file I/O is included: what someone actually types.

libstb is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{libstb}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): OpenCV 0.9×, Pillow 1.7×, imageio 2.7× as long.

libstb needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{libstb}}}\right]\): OpenCV 4.2×, Pillow 4.9×, imageio 6.0× as much.

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (88 corpus entries)
gradient/64x64/png
time (lower is better)
libstb 0.109ms · OpenCV 0.136ms · Pillow 0.226ms · imageio 0.366ms
gradient/64x64/jpg
time (lower is better)
libstb 0.071ms · OpenCV 0.072ms · Pillow 0.162ms · imageio 0.317ms
gradient/64x64/bmp
time (lower is better)
OpenCV 0.034ms · libstb 0.047ms · Pillow 0.118ms · imageio 0.257ms
gradient/64x64/tga
time (lower is better)
libstb 0.042ms · Pillow 0.168ms · imageio 0.314ms
gradient/256x256/png
time (lower is better)
libstb 0.775ms · OpenCV 1.01ms · Pillow 1.22ms · imageio 1.41ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
gradient/256x256/jpg
time (lower is better)
OpenCV 0.248ms · libstb 0.319ms · Pillow 0.511ms · imageio 0.663ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB · imageio 0.0MB
gradient/256x256/bmp
time (lower is better)
OpenCV 0.062ms · Pillow 0.209ms · libstb 0.211ms · imageio 0.341ms
gradient/256x256/tga
time (lower is better)
libstb 0.089ms · Pillow 0.261ms · imageio 0.400ms
gradient/1024x1024/png
time (lower is better)
libstb 11.1ms · OpenCV 15.0ms · Pillow 17.4ms · imageio 20.6ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 1.5MB · OpenCV 2.8MB
gradient/1024x1024/jpg
time (lower is better)
OpenCV 2.31ms · libstb 3.57ms · Pillow 3.74ms · imageio 4.18ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 2.1MB · OpenCV 3.0MB
gradient/1024x1024/bmp
time (lower is better)
OpenCV 0.856ms · Pillow 1.94ms · imageio 2.39ms · libstb 3.08ms
gradient/1024x1024/tga
time (lower is better)
libstb 1.38ms · Pillow 2.03ms · imageio 2.48ms
gradient/2048x2048/png
time (lower is better)
libstb 40.4ms · OpenCV 49.9ms · Pillow 58.7ms · imageio 72.1ms
extra peak memory (lower is better)
libstb 11.2MB · OpenCV 20.7MB · Pillow 24.4MB · imageio 40.2MB
gradient/2048x2048/jpg
time (lower is better)
OpenCV 7.92ms · Pillow 11.9ms · libstb 13.6ms · imageio 21.7ms
extra peak memory (lower is better)
libstb 2.5MB · OpenCV 20.8MB · Pillow 24.5MB · imageio 28.7MB
gradient/2048x2048/bmp
time (lower is better)
OpenCV 2.66ms · Pillow 6.49ms · libstb 11.8ms · imageio 16.8ms
gradient/2048x2048/tga
time (lower is better)
libstb 3.85ms · Pillow 6.59ms · imageio 16.1ms
photo/64x64/png
time (lower is better)
libstb 0.132ms · OpenCV 0.159ms · Pillow 0.259ms · imageio 0.401ms
photo/64x64/jpg
time (lower is better)
libstb 0.070ms · OpenCV 0.072ms · Pillow 0.174ms · imageio 0.314ms
photo/64x64/bmp
time (lower is better)
libstb 0.047ms · OpenCV 0.059ms · Pillow 0.117ms · imageio 0.256ms
photo/64x64/tga
time (lower is better)
libstb 0.041ms · Pillow 0.173ms · imageio 0.327ms
photo/256x256/png
time (lower is better)
libstb 0.762ms · OpenCV 1.08ms · Pillow 1.23ms · imageio 1.39ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
photo/256x256/jpg
time (lower is better)
OpenCV 0.285ms · libstb 0.349ms · Pillow 0.376ms · imageio 0.530ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB · imageio 0.0MB
photo/256x256/bmp
time (lower is better)
OpenCV 0.067ms · Pillow 0.210ms · libstb 0.216ms · imageio 0.379ms
photo/256x256/tga
time (lower is better)
libstb 0.090ms · Pillow 0.261ms · imageio 0.413ms
photo/1024x1024/png
time (lower is better)
libstb 8.71ms · OpenCV 12.6ms · Pillow 13.6ms · imageio 14.0ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 1.5MB · OpenCV 2.8MB
photo/1024x1024/jpg
time (lower is better)
OpenCV 2.74ms · Pillow 3.17ms · imageio 3.57ms · libstb 4.22ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 2.1MB · OpenCV 3.0MB
photo/1024x1024/bmp
time (lower is better)
OpenCV 0.677ms · Pillow 1.67ms · imageio 2.36ms · libstb 2.94ms
photo/1024x1024/tga
time (lower is better)
libstb 0.967ms · Pillow 1.71ms · imageio 2.07ms
photo/2048x2048/png
time (lower is better)
libstb 23.7ms · OpenCV 38.2ms · Pillow 41.8ms · imageio 54.0ms
extra peak memory (lower is better)
libstb 14.2MB · OpenCV 20.7MB · Pillow 24.3MB · imageio 40.5MB
photo/2048x2048/jpg
time (lower is better)
OpenCV 8.66ms · Pillow 12.2ms · libstb 15.0ms · imageio 21.1ms
extra peak memory (lower is better)
libstb 2.7MB · OpenCV 20.9MB · Pillow 24.5MB · imageio 28.7MB
photo/2048x2048/bmp
time (lower is better)
OpenCV 2.62ms · Pillow 6.43ms · libstb 11.6ms · imageio 15.5ms
photo/2048x2048/tga
time (lower is better)
libstb 3.80ms · Pillow 6.51ms · imageio 15.7ms
noise/64x64/png
time (lower is better)
libstb 0.051ms · OpenCV 0.068ms · Pillow 0.156ms · imageio 0.299ms
noise/64x64/jpg
time (lower is better)
OpenCV 0.094ms · libstb 0.097ms · Pillow 0.180ms · imageio 0.334ms
noise/64x64/bmp
time (lower is better)
OpenCV 0.031ms · libstb 0.046ms · Pillow 0.116ms · imageio 0.250ms
noise/64x64/tga
time (lower is better)
libstb 0.040ms · Pillow 0.172ms · imageio 0.306ms
noise/256x256/png
time (lower is better)
libstb 0.777ms · OpenCV 1.00ms · Pillow 1.11ms · imageio 1.27ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
noise/256x256/jpg
time (lower is better)
OpenCV 0.640ms · Pillow 0.802ms · libstb 0.819ms · imageio 0.954ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
noise/256x256/bmp
time (lower is better)
OpenCV 0.062ms · Pillow 0.206ms · libstb 0.208ms · imageio 0.346ms
noise/256x256/tga
time (lower is better)
libstb 0.082ms · Pillow 0.254ms · imageio 0.401ms
noise/1024x1024/png
time (lower is better)
libstb 14.5ms · OpenCV 17.8ms · Pillow 18.4ms · imageio 18.8ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 1.6MB · OpenCV 2.9MB
noise/1024x1024/jpg
time (lower is better)
OpenCV 9.20ms · Pillow 9.93ms · imageio 10.5ms · libstb 12.3ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 2.2MB · OpenCV 2.9MB
noise/1024x1024/bmp
time (lower is better)
OpenCV 0.658ms · Pillow 1.70ms · imageio 2.18ms · libstb 2.96ms
noise/1024x1024/tga
time (lower is better)
libstb 1.06ms · Pillow 1.74ms · imageio 2.15ms
noise/2048x2048/png
time (lower is better)
libstb 43.4ms · OpenCV 55.7ms · Pillow 57.0ms · imageio 69.2ms
extra peak memory (lower is better)
libstb 20.4MB · OpenCV 20.7MB · Pillow 24.4MB · imageio 40.4MB
noise/2048x2048/jpg
time (lower is better)
OpenCV 35.8ms · Pillow 38.5ms · libstb 49.0ms · imageio 49.3ms
extra peak memory (lower is better)
libstb 6.1MB · OpenCV 20.8MB · Pillow 24.6MB · imageio 28.8MB
noise/2048x2048/bmp
time (lower is better)
OpenCV 2.59ms · Pillow 6.61ms · libstb 11.8ms · imageio 16.8ms
noise/2048x2048/tga
time (lower is better)
libstb 3.90ms · Pillow 6.66ms · imageio 17.0ms
graphics/64x64/png
time (lower is better)
libstb 0.060ms · OpenCV 0.079ms · Pillow 0.175ms · imageio 0.315ms
graphics/64x64/jpg
time (lower is better)
OpenCV 0.089ms · libstb 0.090ms · Pillow 0.178ms · imageio 0.333ms
graphics/64x64/bmp
time (lower is better)
OpenCV 0.034ms · libstb 0.050ms · Pillow 0.120ms · imageio 0.269ms
graphics/64x64/tga
time (lower is better)
libstb 0.043ms · Pillow 0.168ms · imageio 0.311ms
graphics/256x256/png
time (lower is better)
libstb 0.118ms · OpenCV 0.390ms · Pillow 0.542ms · imageio 0.709ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
graphics/256x256/jpg
time (lower is better)
OpenCV 0.327ms · Pillow 0.408ms · libstb 0.421ms · imageio 0.567ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
graphics/256x256/bmp
time (lower is better)
OpenCV 0.065ms · Pillow 0.214ms · libstb 0.214ms · imageio 0.369ms
graphics/256x256/tga
time (lower is better)
libstb 0.091ms · Pillow 0.238ms · imageio 0.423ms
graphics/1024x1024/png
time (lower is better)
libstb 1.22ms · OpenCV 4.96ms · Pillow 6.19ms · imageio 6.63ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 0.5MB · OpenCV 4.7MB
graphics/1024x1024/jpg
time (lower is better)
OpenCV 2.61ms · Pillow 3.07ms · imageio 3.51ms · libstb 4.31ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 2.1MB · OpenCV 2.9MB
graphics/1024x1024/bmp
time (lower is better)
OpenCV 0.658ms · Pillow 1.70ms · imageio 2.09ms · libstb 3.08ms
graphics/1024x1024/tga
time (lower is better)
libstb 1.17ms · Pillow 1.47ms · imageio 1.90ms
graphics/2048x2048/png
time (lower is better)
libstb 4.11ms · OpenCV 18.8ms · Pillow 23.0ms · imageio 35.0ms
extra peak memory (lower is better)
libstb 16.2MB · OpenCV 28.8MB · Pillow 32.3MB · imageio 36.5MB
graphics/2048x2048/jpg
time (lower is better)
OpenCV 8.39ms · Pillow 10.5ms · libstb 14.8ms · imageio 21.7ms
extra peak memory (lower is better)
libstb 2.7MB · OpenCV 20.9MB · Pillow 24.5MB · imageio 28.8MB
graphics/2048x2048/bmp
time (lower is better)
OpenCV 2.70ms · Pillow 6.54ms · imageio 17.2ms · libstb 17.4ms
graphics/2048x2048/tga
time (lower is better)
libstb 4.90ms · Pillow 5.45ms · imageio 17.8ms
real-baboon/512x512/png
time (lower is better)
libstb 5.06ms · OpenCV 6.02ms · Pillow 6.43ms · imageio 6.71ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-baboon/512x512/jpg
time (lower is better)
OpenCV 1.62ms · Pillow 2.08ms · libstb 2.21ms · imageio 2.31ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-baboon/512x512/bmp
time (lower is better)
OpenCV 0.169ms · Pillow 0.504ms · imageio 0.696ms · libstb 0.736ms
real-baboon/512x512/tga
time (lower is better)
libstb 0.234ms · Pillow 0.574ms · imageio 0.757ms
real-butterfly/493x356/png
time (lower is better)
libstb 3.29ms · OpenCV 4.02ms · Pillow 4.40ms · imageio 4.59ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-butterfly/493x356/jpg
time (lower is better)
OpenCV 0.801ms · Pillow 1.10ms · imageio 1.28ms · libstb 1.31ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-butterfly/493x356/bmp
time (lower is better)
OpenCV 0.120ms · Pillow 0.365ms · libstb 0.531ms · imageio 0.538ms
real-butterfly/493x356/tga
time (lower is better)
libstb 0.161ms · Pillow 0.422ms · imageio 0.579ms
real-fruits/512x480/png
time (lower is better)
libstb 5.22ms · OpenCV 6.39ms · Pillow 7.33ms · imageio 7.46ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-fruits/512x480/jpg
time (lower is better)
OpenCV 1.01ms · Pillow 1.41ms · libstb 1.44ms · imageio 1.62ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-fruits/512x480/bmp
time (lower is better)
OpenCV 0.212ms · Pillow 0.557ms · libstb 0.728ms · imageio 0.753ms
real-fruits/512x480/tga
time (lower is better)
libstb 0.267ms · Pillow 0.625ms · imageio 0.817ms
real-home/512x384/png
time (lower is better)
libstb 3.46ms · OpenCV 4.07ms · Pillow 4.61ms · imageio 4.83ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-home/512x384/jpg
time (lower is better)
OpenCV 0.777ms · Pillow 1.13ms · libstb 1.16ms · imageio 1.29ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-home/512x384/bmp
time (lower is better)
OpenCV 0.133ms · Pillow 0.403ms · imageio 0.556ms · libstb 0.595ms
real-home/512x384/tga
time (lower is better)
libstb 0.186ms · Pillow 0.459ms · imageio 0.635ms
real-lena/512x512/png
time (lower is better)
libstb 5.58ms · OpenCV 6.72ms · Pillow 7.49ms · imageio 7.68ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-lena/512x512/jpg
time (lower is better)
OpenCV 1.14ms · Pillow 1.56ms · libstb 1.59ms · imageio 1.76ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-lena/512x512/bmp
time (lower is better)
OpenCV 0.168ms · Pillow 0.501ms · imageio 0.693ms · libstb 0.759ms
real-lena/512x512/tga
time (lower is better)
libstb 0.219ms · Pillow 0.547ms · imageio 0.717ms
real-messi5/548x342/png
time (lower is better)
libstb 3.57ms · OpenCV 4.35ms · Pillow 4.94ms · imageio 5.13ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-messi5/548x342/jpg
time (lower is better)
OpenCV 0.765ms · Pillow 0.915ms · imageio 1.09ms · libstb 1.13ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-messi5/548x342/bmp
time (lower is better)
OpenCV 0.127ms · Pillow 0.381ms · libstb 0.530ms · imageio 0.549ms
real-messi5/548x342/tga
time (lower is better)
libstb 0.162ms · Pillow 0.432ms · imageio 0.624ms
Encoding

Writing images

Raw pixels to file bytes, at matched settings. Speed alone is not the whole story for an encoder, so each panel also shows how large the output is. Speed is the best of 7 runs; memory is the extra peak RSS of one isolated process per measurement.

encode PNG: raw pixels in, file bytes out

zlib level 6 on every side. stb bundles its own small deflate instead of zlib, so the same level does not produce the same bytes: read the speed together with the output-size table below.

libstb is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{libstb}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): OpenCV 1.7×, Pillow 2.1×, imageio 2.3× as long.

libstb needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{libstb}}}\right]\): Pillow 0.0×, OpenCV 0.0×, imageio 1.3× as much.

Output size\(\mathbb{E}\!\left[\dfrac{s_{L}}{s_{\text{ Pillow }}}\right]\)entries
libstb1.01×22
OpenCV1.02×22
imageio1.00×22

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (22 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.212ms · OpenCV 0.270ms · Pillow 0.395ms · imageio 0.547ms
gradient/256x256
time (lower is better)
libstb 9.88ms · OpenCV 11.4ms · Pillow 11.9ms · imageio 12.0ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
gradient/1024x1024
time (lower is better)
libstb 191.9ms · OpenCV 215.9ms · imageio 226.2ms · Pillow 226.2ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · imageio 0.0MB · Pillow 0.0MB
gradient/2048x2048
time (lower is better)
libstb 557.8ms · OpenCV 673.5ms · Pillow 705.8ms · imageio 710.9ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 10.4MB · imageio 20.6MB
photo/64x64
time (lower is better)
libstb 0.187ms · OpenCV 0.320ms · Pillow 0.489ms · imageio 0.648ms
photo/256x256
time (lower is better)
libstb 3.87ms · OpenCV 7.99ms · Pillow 11.4ms · imageio 11.6ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
photo/1024x1024
time (lower is better)
libstb 47.1ms · OpenCV 102.1ms · Pillow 141.1ms · imageio 141.3ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
photo/2048x2048
time (lower is better)
libstb 127.8ms · OpenCV 277.6ms · Pillow 372.1ms · imageio 375.8ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 12.3MB · imageio 22.3MB
noise/64x64
time (lower is better)
libstb 0.159ms · OpenCV 0.234ms · Pillow 0.394ms · imageio 0.551ms
noise/256x256
time (lower is better)
libstb 3.46ms · OpenCV 4.85ms · Pillow 6.83ms · imageio 7.02ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
noise/1024x1024
time (lower is better)
libstb 50.4ms · OpenCV 80.3ms · Pillow 112.2ms · imageio 113.4ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 1.1MB · OpenCV 2.3MB
noise/2048x2048
time (lower is better)
libstb 203.5ms · OpenCV 327.8ms · Pillow 451.5ms · imageio 454.3ms
extra peak memory (lower is better)
Pillow 2.1MB · OpenCV 5.4MB · imageio 31.2MB · libstb 32.1MB
graphics/64x64
time (lower is better)
libstb 0.115ms · OpenCV 0.178ms · Pillow 0.210ms · imageio 0.365ms
graphics/256x256
time (lower is better)
libstb 0.783ms · Pillow 1.22ms · imageio 1.38ms · OpenCV 1.57ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 0.0MB · OpenCV 0.0MB
graphics/1024x1024
time (lower is better)
libstb 11.7ms · Pillow 17.7ms · imageio 17.9ms · OpenCV 24.6ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB · imageio 0.0MB · OpenCV 0.0MB
graphics/2048x2048
time (lower is better)
libstb 45.6ms · Pillow 67.3ms · imageio 67.8ms · OpenCV 97.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 1.4MB · imageio 6.3MB · libstb 16.8MB
real-baboon/512x512
time (lower is better)
libstb 14.4ms · OpenCV 26.2ms · Pillow 31.6ms · imageio 32.0ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-butterfly/493x356
time (lower is better)
libstb 16.3ms · OpenCV 31.3ms · Pillow 39.3ms · imageio 39.8ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-fruits/512x480
time (lower is better)
libstb 27.0ms · OpenCV 47.7ms · Pillow 65.5ms · imageio 66.4ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-home/512x384
time (lower is better)
libstb 17.5ms · OpenCV 27.2ms · Pillow 30.1ms · imageio 30.5ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-lena/512x512
time (lower is better)
libstb 27.2ms · OpenCV 50.4ms · Pillow 67.8ms · imageio 68.0ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB
real-messi5/548x342
time (lower is better)
libstb 24.5ms · OpenCV 39.2ms · Pillow 49.3ms · imageio 49.8ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB

encode JPEG: raw pixels in, file bytes out

Quality 90 on every side, 3-channel images only. Encoders make different size/quality trades at the same setting, so the output-size table matters as much as the time.

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): Pillow 1.2×, imageio 2.1×, libstb 2.2× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Output size\(\mathbb{E}\!\left[\dfrac{s_{L}}{s_{\text{ Pillow }}}\right]\)entries
libstb0.99×18
OpenCV1.00×18
imageio1.00×18

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.035ms · OpenCV 0.040ms · Pillow 0.076ms · imageio 0.220ms
gradient/256x256
time (lower is better)
OpenCV 0.165ms · Pillow 0.206ms · libstb 0.336ms · imageio 0.394ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
gradient/1024x1024
time (lower is better)
OpenCV 1.76ms · Pillow 1.90ms · imageio 2.48ms · libstb 4.70ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
gradient/2048x2048
time (lower is better)
OpenCV 7.08ms · Pillow 7.55ms · imageio 9.39ms · libstb 19.3ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 19.4MB
photo/64x64
time (lower is better)
libstb 0.038ms · OpenCV 0.043ms · Pillow 0.079ms · imageio 0.229ms
photo/256x256
time (lower is better)
OpenCV 0.180ms · Pillow 0.219ms · libstb 0.385ms · imageio 0.410ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
photo/1024x1024
time (lower is better)
OpenCV 2.10ms · Pillow 2.23ms · imageio 2.90ms · libstb 5.51ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
photo/2048x2048
time (lower is better)
OpenCV 7.51ms · Pillow 7.89ms · imageio 9.79ms · libstb 20.2ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 19.5MB
noise/64x64
time (lower is better)
OpenCV 0.052ms · libstb 0.065ms · Pillow 0.088ms · imageio 0.232ms
noise/256x256
time (lower is better)
OpenCV 0.370ms · Pillow 0.413ms · imageio 0.583ms · libstb 0.928ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
noise/1024x1024
time (lower is better)
Pillow 5.50ms · OpenCV 5.71ms · imageio 6.16ms · libstb 14.9ms
extra peak memory (lower is better)
Pillow 0.0MB · OpenCV 0.0MB · imageio 0.0MB · libstb 0.0MB
noise/2048x2048
time (lower is better)
Pillow 21.9ms · OpenCV 23.0ms · imageio 24.1ms · libstb 59.5ms
extra peak memory (lower is better)
Pillow 0.0MB · OpenCV 0.0MB · libstb 3.6MB · imageio 23.9MB
real-baboon/512x512
time (lower is better)
OpenCV 1.04ms · Pillow 1.10ms · imageio 1.49ms · libstb 2.68ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.571ms · Pillow 0.618ms · imageio 0.875ms · libstb 1.35ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-fruits/512x480
time (lower is better)
OpenCV 0.701ms · Pillow 0.749ms · imageio 1.01ms · libstb 1.74ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-home/512x384
time (lower is better)
OpenCV 0.507ms · Pillow 0.576ms · imageio 0.788ms · libstb 1.24ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-lena/512x512
time (lower is better)
OpenCV 0.776ms · Pillow 0.806ms · imageio 1.08ms · libstb 1.90ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-messi5/548x342
time (lower is better)
OpenCV 0.569ms · Pillow 0.599ms · imageio 0.837ms · libstb 1.37ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB

encode BMP: raw pixels in, file bytes out

Uncompressed, so this is mostly memory bandwidth. 3-channel images only.

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): Pillow 2.0×, libstb 2.3×, imageio 5.1× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{OpenCV}}}\right]\): Pillow 1.1×, libstb 13.7×, imageio 18.2× as much.

Output size\(\mathbb{E}\!\left[\dfrac{s_{L}}{s_{\text{ Pillow }}}\right]\)entries
libstb1.00×18
OpenCV1.00×18
imageio1.00×18

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.013ms · OpenCV 0.017ms · Pillow 0.053ms · imageio 0.198ms
gradient/256x256
time (lower is better)
OpenCV 0.046ms · Pillow 0.098ms · libstb 0.105ms · imageio 0.288ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
gradient/1024x1024
time (lower is better)
OpenCV 0.702ms · Pillow 0.906ms · imageio 1.55ms · libstb 1.68ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · OpenCV 0.9MB · imageio 0.9MB
gradient/2048x2048
time (lower is better)
OpenCV 3.38ms · Pillow 4.06ms · imageio 6.59ms · libstb 6.97ms
extra peak memory (lower is better)
OpenCV 0.9MB · Pillow 2.0MB · libstb 23.8MB · imageio 30.6MB
photo/64x64
time (lower is better)
libstb 0.014ms · OpenCV 0.018ms · Pillow 0.054ms · imageio 0.211ms
photo/256x256
time (lower is better)
OpenCV 0.047ms · Pillow 0.099ms · libstb 0.103ms · imageio 0.283ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
photo/1024x1024
time (lower is better)
OpenCV 0.757ms · Pillow 1.09ms · libstb 1.79ms · imageio 1.81ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · OpenCV 0.9MB · imageio 1.0MB
photo/2048x2048
time (lower is better)
OpenCV 2.79ms · Pillow 3.51ms · imageio 5.56ms · libstb 6.88ms
extra peak memory (lower is better)
OpenCV 0.8MB · Pillow 2.0MB · libstb 23.8MB · imageio 30.6MB
noise/64x64
time (lower is better)
libstb 0.013ms · OpenCV 0.018ms · Pillow 0.055ms · imageio 0.202ms
noise/256x256
time (lower is better)
OpenCV 0.045ms · Pillow 0.101ms · libstb 0.103ms · imageio 0.268ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
noise/1024x1024
time (lower is better)
OpenCV 0.728ms · Pillow 1.10ms · libstb 1.69ms · imageio 1.75ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · OpenCV 0.9MB · imageio 1.0MB
noise/2048x2048
time (lower is better)
OpenCV 2.85ms · Pillow 3.60ms · imageio 5.55ms · libstb 6.89ms
extra peak memory (lower is better)
OpenCV 0.9MB · Pillow 2.0MB · libstb 23.9MB · imageio 30.6MB
real-baboon/512x512
time (lower is better)
OpenCV 0.175ms · Pillow 0.335ms · libstb 0.436ms · imageio 0.664ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.094ms · Pillow 0.230ms · libstb 0.301ms · imageio 0.480ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-fruits/512x480
time (lower is better)
OpenCV 0.125ms · Pillow 0.253ms · libstb 0.399ms · imageio 0.530ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-home/512x384
time (lower is better)
OpenCV 0.116ms · Pillow 0.253ms · libstb 0.310ms · imageio 0.474ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-lena/512x512
time (lower is better)
OpenCV 0.129ms · Pillow 0.220ms · libstb 0.376ms · imageio 0.503ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-messi5/548x342
time (lower is better)
OpenCV 0.093ms · Pillow 0.219ms · libstb 0.290ms · imageio 0.461ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB

encode TGA: raw pixels in, file bytes out

Uncompressed on every side (libstb with rle=False, matching Pillow's default). OpenCV has no TGA encoder.

Pillow is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{Pillow}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 1.4×, imageio 2.3× as long.

Pillow needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{Pillow}}}\right]\): libstb 4.9×, imageio 5.8× as much.

Output size\(\mathbb{E}\!\left[\dfrac{s_{L}}{s_{\text{ Pillow }}}\right]\)entries
libstb1.00×22
imageio1.00×22

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (22 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.013ms · Pillow 0.053ms · imageio 0.194ms
gradient/256x256
time (lower is better)
Pillow 0.096ms · libstb 0.103ms · imageio 0.266ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
gradient/1024x1024
time (lower is better)
Pillow 0.886ms · imageio 1.48ms · libstb 1.67ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.8MB
gradient/2048x2048
time (lower is better)
Pillow 4.10ms · imageio 6.75ms · libstb 7.68ms
extra peak memory (lower is better)
Pillow 4.1MB · libstb 23.6MB · imageio 30.6MB
photo/64x64
time (lower is better)
libstb 0.014ms · Pillow 0.051ms · imageio 0.201ms
photo/256x256
time (lower is better)
Pillow 0.096ms · libstb 0.106ms · imageio 0.282ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
photo/1024x1024
time (lower is better)
Pillow 1.08ms · libstb 1.74ms · imageio 1.74ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.9MB
photo/2048x2048
time (lower is better)
Pillow 3.44ms · imageio 5.36ms · libstb 6.88ms
extra peak memory (lower is better)
Pillow 4.2MB · libstb 23.6MB · imageio 30.8MB
noise/64x64
time (lower is better)
libstb 0.014ms · Pillow 0.051ms · imageio 0.200ms
noise/256x256
time (lower is better)
Pillow 0.096ms · libstb 0.103ms · imageio 0.267ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
noise/1024x1024
time (lower is better)
Pillow 1.08ms · libstb 1.68ms · imageio 1.74ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 1.0MB
noise/2048x2048
time (lower is better)
Pillow 3.60ms · imageio 5.65ms · libstb 6.89ms
extra peak memory (lower is better)
Pillow 4.2MB · libstb 23.6MB · imageio 30.6MB
graphics/64x64
time (lower is better)
libstb 0.018ms · Pillow 0.051ms · imageio 0.195ms
graphics/256x256
time (lower is better)
Pillow 0.115ms · libstb 0.162ms · imageio 0.264ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
graphics/1024x1024
time (lower is better)
Pillow 0.942ms · imageio 1.09ms · libstb 2.44ms
extra peak memory (lower is better)
Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
graphics/2048x2048
time (lower is better)
Pillow 3.41ms · imageio 3.46ms · libstb 9.94ms
extra peak memory (lower is better)
Pillow 19.3MB · imageio 22.1MB · libstb 47.9MB
real-baboon/512x512
time (lower is better)
Pillow 0.322ms · libstb 0.450ms · imageio 0.651ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-butterfly/493x356
time (lower is better)
Pillow 0.219ms · libstb 0.262ms · imageio 0.440ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-fruits/512x480
time (lower is better)
Pillow 0.443ms · imageio 0.618ms · libstb 0.656ms
extra peak memory (lower is better)
Pillow 0.0MB · imageio 0.0MB · libstb 0.0MB
real-home/512x384
time (lower is better)
Pillow 0.256ms · libstb 0.310ms · imageio 0.465ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-lena/512x512
time (lower is better)
Pillow 0.216ms · libstb 0.372ms · imageio 0.481ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
real-messi5/548x342
time (lower is better)
Pillow 0.209ms · libstb 0.277ms · imageio 0.441ms
extra peak memory (lower is better)
Pillow 0.0MB · libstb 0.0MB · imageio 0.0MB
Resizing

Resizing images

Half size and double size, with linear, cubic and box filters. Speed is the best of 7 runs; memory is the extra peak RSS of one isolated process per measurement.

resize, half size, linear (triangle)

libstb, Pillow and scikit-image prefilter when shrinking; OpenCV's INTER_LINEAR and INTER_CUBIC do not (faster, and they alias), and INTER_AREA is its antialiasing counterpart. "libstb" is Resizer(filter, srgb=False), the like-for-like pairing; "libstb (sRGB-correct)" is the library's own default, which blends in linear light like a correct resizer should, listed separately so the price of that is visible. 3-channel images only. scikit-image is skipped above 1 MP (seconds per call).

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 2.8×, libstb (sRGB-correct) 6.7×, Pillow 10.6×, scikit-image 155.3× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.014ms · OpenCV 0.015ms · libstb (sRGB-correct) 0.019ms · Pillow 0.038ms · scikit-image 0.354ms
gradient/256x256
time (lower is better)
OpenCV 0.033ms · libstb 0.077ms · libstb (sRGB-correct) 0.174ms · Pillow 0.287ms · scikit-image 4.70ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 4.0MB
gradient/1024x1024
time (lower is better)
OpenCV 0.257ms · libstb 1.04ms · libstb (sRGB-correct) 2.69ms · Pillow 4.30ms · scikit-image 83.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 54.7MB
gradient/2048x2048
time (lower is better)
OpenCV 1.09ms · libstb 4.55ms · libstb (sRGB-correct) 11.2ms · Pillow 17.1ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
photo/64x64
time (lower is better)
libstb 0.014ms · OpenCV 0.016ms · libstb (sRGB-correct) 0.020ms · Pillow 0.038ms · scikit-image 0.360ms
photo/256x256
time (lower is better)
OpenCV 0.032ms · libstb 0.076ms · libstb (sRGB-correct) 0.174ms · Pillow 0.289ms · scikit-image 3.97ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 4.0MB
photo/1024x1024
time (lower is better)
OpenCV 0.280ms · libstb 1.06ms · libstb (sRGB-correct) 2.70ms · Pillow 4.25ms · scikit-image 91.3ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 54.7MB
photo/2048x2048
time (lower is better)
OpenCV 0.976ms · libstb 4.38ms · libstb (sRGB-correct) 11.0ms · Pillow 16.7ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
noise/64x64
time (lower is better)
libstb 0.014ms · OpenCV 0.016ms · libstb (sRGB-correct) 0.020ms · Pillow 0.039ms · scikit-image 0.363ms
noise/256x256
time (lower is better)
OpenCV 0.031ms · libstb 0.076ms · libstb (sRGB-correct) 0.174ms · Pillow 0.280ms · scikit-image 3.99ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 3.9MB
noise/1024x1024
time (lower is better)
OpenCV 0.264ms · libstb 1.05ms · libstb (sRGB-correct) 2.71ms · Pillow 4.26ms · scikit-image 91.6ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 54.6MB
noise/2048x2048
time (lower is better)
OpenCV 0.968ms · libstb 4.36ms · libstb (sRGB-correct) 10.9ms · Pillow 16.9ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
real-baboon/512x512
time (lower is better)
OpenCV 0.165ms · libstb 0.270ms · libstb (sRGB-correct) 0.669ms · Pillow 1.10ms · scikit-image 19.9ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 14.2MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.101ms · libstb 0.201ms · libstb (sRGB-correct) 0.469ms · Pillow 0.737ms · scikit-image 8.89ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 9.7MB
real-fruits/512x480
time (lower is better)
OpenCV 0.112ms · libstb 0.255ms · libstb (sRGB-correct) 0.632ms · Pillow 1.01ms · scikit-image 16.3ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 13.5MB
real-home/512x384
time (lower is better)
OpenCV 0.074ms · libstb 0.202ms · libstb (sRGB-correct) 0.508ms · Pillow 0.810ms · scikit-image 12.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 10.9MB
real-lena/512x512
time (lower is better)
OpenCV 0.085ms · libstb 0.258ms · libstb (sRGB-correct) 0.661ms · Pillow 1.06ms · scikit-image 16.1ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 14.2MB
real-messi5/548x342
time (lower is better)
OpenCV 0.061ms · libstb 0.190ms · libstb (sRGB-correct) 0.483ms · Pillow 0.767ms · scikit-image 9.87ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 10.4MB

resize, half size, cubic (Catmull-Rom)

libstb, Pillow and scikit-image prefilter when shrinking; OpenCV's INTER_LINEAR and INTER_CUBIC do not (faster, and they alias), and INTER_AREA is its antialiasing counterpart. "libstb" is Resizer(filter, srgb=False), the like-for-like pairing; "libstb (sRGB-correct)" is the library's own default, which blends in linear light like a correct resizer should, listed separately so the price of that is visible. 3-channel images only. scikit-image is skipped above 1 MP (seconds per call).

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 1.8×, libstb (sRGB-correct) 3.6×, Pillow 7.9×, scikit-image 352.1× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.017ms · libstb (sRGB-correct) 0.022ms · OpenCV 0.024ms · Pillow 0.050ms · scikit-image 1.36ms
gradient/256x256
time (lower is better)
OpenCV 0.070ms · libstb 0.107ms · libstb (sRGB-correct) 0.205ms · Pillow 0.463ms · scikit-image 21.6ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 5.6MB
gradient/1024x1024
time (lower is better)
OpenCV 0.672ms · libstb 1.59ms · libstb (sRGB-correct) 3.15ms · Pillow 7.08ms · scikit-image 389.5ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 78.8MB
gradient/2048x2048
time (lower is better)
OpenCV 2.63ms · libstb 6.24ms · libstb (sRGB-correct) 13.0ms · Pillow 28.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.1MB
photo/64x64
time (lower is better)
libstb 0.016ms · libstb (sRGB-correct) 0.022ms · OpenCV 0.023ms · Pillow 0.050ms · scikit-image 1.36ms
photo/256x256
time (lower is better)
OpenCV 0.067ms · libstb 0.108ms · libstb (sRGB-correct) 0.206ms · Pillow 0.463ms · scikit-image 20.5ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 5.6MB
photo/1024x1024
time (lower is better)
OpenCV 0.763ms · libstb 1.56ms · libstb (sRGB-correct) 3.14ms · Pillow 7.05ms · scikit-image 407.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 78.6MB
photo/2048x2048
time (lower is better)
OpenCV 2.36ms · libstb 6.15ms · libstb (sRGB-correct) 12.6ms · Pillow 27.8ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.1MB
noise/64x64
time (lower is better)
libstb 0.016ms · libstb (sRGB-correct) 0.022ms · OpenCV 0.023ms · Pillow 0.050ms · scikit-image 1.34ms
noise/256x256
time (lower is better)
OpenCV 0.066ms · libstb 0.109ms · libstb (sRGB-correct) 0.204ms · Pillow 0.454ms · scikit-image 20.5ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 5.6MB
noise/1024x1024
time (lower is better)
OpenCV 0.649ms · libstb 1.52ms · libstb (sRGB-correct) 3.22ms · Pillow 7.11ms · scikit-image 401.3ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 78.7MB
noise/2048x2048
time (lower is better)
OpenCV 2.33ms · libstb 6.10ms · libstb (sRGB-correct) 12.7ms · Pillow 28.1ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.1MB
real-baboon/512x512
time (lower is better)
OpenCV 0.312ms · libstb 0.412ms · libstb (sRGB-correct) 0.800ms · Pillow 1.85ms · scikit-image 88.6ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 20.4MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.138ms · libstb 0.286ms · libstb (sRGB-correct) 0.554ms · Pillow 1.16ms · scikit-image 51.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 13.7MB
real-fruits/512x480
time (lower is better)
OpenCV 0.199ms · libstb 0.375ms · libstb (sRGB-correct) 0.745ms · Pillow 1.70ms · scikit-image 79.8ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 19.0MB
real-home/512x384
time (lower is better)
OpenCV 0.149ms · libstb 0.294ms · libstb (sRGB-correct) 0.600ms · Pillow 1.33ms · scikit-image 62.1ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 15.3MB
real-lena/512x512
time (lower is better)
OpenCV 0.190ms · libstb 0.387ms · libstb (sRGB-correct) 0.792ms · Pillow 1.79ms · scikit-image 83.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 20.2MB
real-messi5/548x342
time (lower is better)
OpenCV 0.141ms · libstb 0.280ms · libstb (sRGB-correct) 0.576ms · Pillow 1.25ms · scikit-image 76.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 14.7MB

resize, half size, box / area

libstb, Pillow and scikit-image prefilter when shrinking; OpenCV's INTER_LINEAR and INTER_CUBIC do not (faster, and they alias), and INTER_AREA is its antialiasing counterpart. "libstb" is Resizer(filter, srgb=False), the like-for-like pairing; "libstb (sRGB-correct)" is the library's own default, which blends in linear light like a correct resizer should, listed separately so the price of that is visible. 3-channel images only. scikit-image is skipped above 1 MP (seconds per call). scikit-image has no box filter.

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 2.0×, libstb (sRGB-correct) 5.9×, Pillow 7.0× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.012ms · OpenCV 0.016ms · libstb (sRGB-correct) 0.018ms · Pillow 0.031ms
gradient/256x256
time (lower is better)
OpenCV 0.032ms · libstb 0.058ms · libstb (sRGB-correct) 0.156ms · Pillow 0.199ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
gradient/1024x1024
time (lower is better)
OpenCV 0.271ms · libstb 0.724ms · libstb (sRGB-correct) 2.37ms · Pillow 2.85ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
gradient/2048x2048
time (lower is better)
OpenCV 1.07ms · libstb 3.57ms · libstb (sRGB-correct) 10.2ms · Pillow 11.2ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
photo/64x64
time (lower is better)
libstb 0.013ms · OpenCV 0.016ms · libstb (sRGB-correct) 0.019ms · Pillow 0.032ms
photo/256x256
time (lower is better)
OpenCV 0.033ms · libstb 0.059ms · libstb (sRGB-correct) 0.157ms · Pillow 0.196ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
photo/1024x1024
time (lower is better)
OpenCV 0.275ms · libstb 0.733ms · libstb (sRGB-correct) 2.36ms · Pillow 2.78ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
photo/2048x2048
time (lower is better)
OpenCV 0.971ms · libstb 3.44ms · libstb (sRGB-correct) 10.00ms · Pillow 11.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
noise/64x64
time (lower is better)
libstb 0.012ms · OpenCV 0.015ms · libstb (sRGB-correct) 0.018ms · Pillow 0.032ms
noise/256x256
time (lower is better)
OpenCV 0.031ms · libstb 0.059ms · libstb (sRGB-correct) 0.157ms · Pillow 0.193ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
noise/1024x1024
time (lower is better)
OpenCV 0.263ms · libstb 0.746ms · libstb (sRGB-correct) 2.37ms · Pillow 2.81ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
noise/2048x2048
time (lower is better)
OpenCV 0.971ms · libstb 3.34ms · libstb (sRGB-correct) 9.95ms · Pillow 11.1ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
real-baboon/512x512
time (lower is better)
OpenCV 0.105ms · libstb 0.192ms · libstb (sRGB-correct) 0.595ms · Pillow 0.747ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
real-butterfly/493x356
time (lower is better)
libstb 0.150ms · libstb (sRGB-correct) 0.418ms · OpenCV 0.465ms · Pillow 0.487ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
real-fruits/512x480
time (lower is better)
OpenCV 0.172ms · libstb 0.215ms · libstb (sRGB-correct) 0.575ms · Pillow 0.676ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
real-home/512x384
time (lower is better)
OpenCV 0.064ms · libstb 0.151ms · libstb (sRGB-correct) 0.450ms · Pillow 0.541ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
real-lena/512x512
time (lower is better)
OpenCV 0.076ms · libstb 0.189ms · libstb (sRGB-correct) 0.593ms · Pillow 0.721ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB
real-messi5/548x342
time (lower is better)
OpenCV 0.066ms · libstb 0.144ms · libstb (sRGB-correct) 0.432ms · Pillow 0.512ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB

resize, double size, linear (triangle)

libstb, Pillow and scikit-image prefilter when shrinking; OpenCV's INTER_LINEAR and INTER_CUBIC do not (faster, and they alias), and INTER_AREA is its antialiasing counterpart. "libstb" is Resizer(filter, srgb=False), the like-for-like pairing; "libstb (sRGB-correct)" is the library's own default, which blends in linear light like a correct resizer should, listed separately so the price of that is visible. 3-channel images only. scikit-image is skipped above 1 MP (seconds per call).

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 1.5×, libstb (sRGB-correct) 3.4×, Pillow 5.5×, scikit-image 130.8× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{OpenCV}}}\right]\): libstb (sRGB-correct) 0.9×, libstb 0.9×, Pillow 2.6×, scikit-image 18.3× as much.

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.030ms · OpenCV 0.032ms · libstb (sRGB-correct) 0.059ms · Pillow 0.107ms · scikit-image 2.23ms
gradient/256x256
time (lower is better)
OpenCV 0.243ms · libstb 0.334ms · libstb (sRGB-correct) 0.798ms · Pillow 1.37ms · scikit-image 34.1ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 7.8MB
gradient/1024x1024
time (lower is better)
OpenCV 3.62ms · libstb 6.34ms · libstb (sRGB-correct) 14.2ms · Pillow 21.5ms · scikit-image 538.0ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · OpenCV 6.5MB · Pillow 11.2MB · scikit-image 120.3MB
gradient/2048x2048
time (lower is better)
OpenCV 18.8ms · libstb 38.1ms · libstb (sRGB-correct) 69.3ms · Pillow 116.2ms
extra peak memory (lower is better)
OpenCV 24.7MB · libstb (sRGB-correct) 44.1MB · libstb 44.2MB · Pillow 84.3MB
photo/64x64
time (lower is better)
libstb 0.031ms · OpenCV 0.033ms · libstb (sRGB-correct) 0.059ms · Pillow 0.107ms · scikit-image 2.21ms
photo/256x256
time (lower is better)
OpenCV 0.246ms · libstb 0.330ms · libstb (sRGB-correct) 0.813ms · Pillow 1.36ms · scikit-image 34.2ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 7.9MB
photo/1024x1024
time (lower is better)
OpenCV 3.63ms · libstb 6.41ms · libstb (sRGB-correct) 14.1ms · Pillow 21.1ms · scikit-image 539.8ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · OpenCV 6.7MB · Pillow 11.1MB · scikit-image 120.4MB
photo/2048x2048
time (lower is better)
OpenCV 18.1ms · libstb 37.8ms · libstb (sRGB-correct) 68.7ms · Pillow 114.5ms
extra peak memory (lower is better)
OpenCV 24.7MB · libstb 44.0MB · libstb (sRGB-correct) 44.2MB · Pillow 84.3MB
noise/64x64
time (lower is better)
libstb 0.031ms · OpenCV 0.032ms · libstb (sRGB-correct) 0.059ms · Pillow 0.105ms · scikit-image 2.13ms
noise/256x256
time (lower is better)
OpenCV 0.242ms · libstb 0.322ms · libstb (sRGB-correct) 0.800ms · Pillow 1.36ms · scikit-image 34.1ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 7.9MB
noise/1024x1024
time (lower is better)
OpenCV 3.64ms · libstb 6.24ms · libstb (sRGB-correct) 14.1ms · Pillow 21.6ms · scikit-image 533.2ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · OpenCV 6.6MB · Pillow 11.1MB · scikit-image 120.4MB
noise/2048x2048
time (lower is better)
OpenCV 18.6ms · libstb 37.0ms · libstb (sRGB-correct) 68.4ms · Pillow 115.7ms
extra peak memory (lower is better)
OpenCV 24.7MB · libstb (sRGB-correct) 44.1MB · libstb 44.2MB · Pillow 84.3MB
real-baboon/512x512
time (lower is better)
OpenCV 0.907ms · libstb 1.42ms · libstb (sRGB-correct) 3.33ms · Pillow 5.40ms · scikit-image 136.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 30.2MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.607ms · libstb 0.887ms · libstb (sRGB-correct) 2.20ms · Pillow 3.61ms · scikit-image 90.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 20.5MB
real-fruits/512x480
time (lower is better)
OpenCV 0.861ms · libstb 1.36ms · libstb (sRGB-correct) 3.16ms · Pillow 4.97ms · scikit-image 126.3ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 28.6MB
real-home/512x384
time (lower is better)
OpenCV 0.681ms · libstb 1.04ms · libstb (sRGB-correct) 2.49ms · Pillow 4.10ms · scikit-image 102.7ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 22.9MB
real-lena/512x512
time (lower is better)
OpenCV 0.891ms · libstb 1.40ms · libstb (sRGB-correct) 3.35ms · Pillow 5.36ms · scikit-image 132.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 30.3MB
real-messi5/548x342
time (lower is better)
OpenCV 0.647ms · libstb 0.977ms · libstb (sRGB-correct) 2.40ms · Pillow 3.82ms · scikit-image 97.7ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 21.8MB

resize, double size, cubic (Catmull-Rom)

libstb, Pillow and scikit-image prefilter when shrinking; OpenCV's INTER_LINEAR and INTER_CUBIC do not (faster, and they alias), and INTER_AREA is its antialiasing counterpart. "libstb" is Resizer(filter, srgb=False), the like-for-like pairing; "libstb (sRGB-correct)" is the library's own default, which blends in linear light like a correct resizer should, listed separately so the price of that is visible. 3-channel images only. scikit-image is skipped above 1 MP (seconds per call).

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 2.1×, libstb (sRGB-correct) 3.9×, Pillow 8.0×, scikit-image 872.2× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{OpenCV}}}\right]\): libstb (sRGB-correct) 0.6×, libstb 0.6×, Pillow 1.8×, scikit-image 118.1× as much.

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
OpenCV 0.039ms · libstb 0.041ms · libstb (sRGB-correct) 0.070ms · Pillow 0.151ms · scikit-image 14.1ms
gradient/256x256
time (lower is better)
OpenCV 0.244ms · libstb 0.475ms · libstb (sRGB-correct) 0.965ms · Pillow 2.02ms · scikit-image 228.0ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 9.6MB
gradient/1024x1024
time (lower is better)
OpenCV 3.62ms · libstb 8.52ms · libstb (sRGB-correct) 16.3ms · Pillow 31.4ms · scikit-image 3735.6ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · OpenCV 7.7MB · Pillow 11.3MB · scikit-image 144.4MB
gradient/2048x2048
time (lower is better)
OpenCV 18.7ms · libstb 46.5ms · libstb (sRGB-correct) 77.3ms · Pillow 163.1ms
extra peak memory (lower is better)
OpenCV 25.9MB · libstb 44.1MB · libstb (sRGB-correct) 44.2MB · Pillow 84.4MB
photo/64x64
time (lower is better)
OpenCV 0.039ms · libstb 0.041ms · libstb (sRGB-correct) 0.069ms · Pillow 0.149ms · scikit-image 14.1ms
photo/256x256
time (lower is better)
OpenCV 0.242ms · libstb 0.471ms · libstb (sRGB-correct) 0.947ms · Pillow 2.04ms · scikit-image 228.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 9.6MB
photo/1024x1024
time (lower is better)
OpenCV 3.43ms · libstb 8.53ms · libstb (sRGB-correct) 16.3ms · Pillow 31.5ms · scikit-image 3705.4ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · OpenCV 7.7MB · Pillow 11.0MB · scikit-image 144.5MB
photo/2048x2048
time (lower is better)
OpenCV 16.5ms · libstb 46.3ms · libstb (sRGB-correct) 77.6ms · Pillow 161.7ms
extra peak memory (lower is better)
OpenCV 25.9MB · libstb (sRGB-correct) 44.1MB · libstb 44.3MB · Pillow 84.4MB
noise/64x64
time (lower is better)
OpenCV 0.039ms · libstb 0.041ms · libstb (sRGB-correct) 0.069ms · Pillow 0.147ms · scikit-image 14.1ms
noise/256x256
time (lower is better)
OpenCV 0.242ms · libstb 0.468ms · libstb (sRGB-correct) 0.949ms · Pillow 1.99ms · scikit-image 226.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 9.6MB
noise/1024x1024
time (lower is better)
OpenCV 3.46ms · libstb 8.45ms · libstb (sRGB-correct) 16.2ms · Pillow 32.0ms · scikit-image 3730.8ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · OpenCV 7.7MB · Pillow 11.1MB · scikit-image 144.4MB
noise/2048x2048
time (lower is better)
OpenCV 17.1ms · libstb 42.9ms · libstb (sRGB-correct) 74.3ms · Pillow 165.0ms
extra peak memory (lower is better)
OpenCV 25.9MB · libstb (sRGB-correct) 44.1MB · libstb 44.1MB · Pillow 84.4MB
real-baboon/512x512
time (lower is better)
OpenCV 0.871ms · libstb 1.86ms · libstb (sRGB-correct) 3.82ms · Pillow 7.91ms · scikit-image 912.6ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · OpenCV 0.1MB · scikit-image 36.4MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.680ms · libstb 1.28ms · libstb (sRGB-correct) 2.55ms · Pillow 5.31ms · scikit-image 606.4ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 24.5MB
real-fruits/512x480
time (lower is better)
OpenCV 0.797ms · libstb 1.91ms · libstb (sRGB-correct) 3.73ms · Pillow 7.41ms · scikit-image 850.6ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 34.2MB
real-home/512x384
time (lower is better)
OpenCV 0.677ms · libstb 1.49ms · libstb (sRGB-correct) 2.94ms · Pillow 6.00ms · scikit-image 683.7ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 27.5MB
real-lena/512x512
time (lower is better)
OpenCV 0.907ms · libstb 2.05ms · libstb (sRGB-correct) 4.01ms · Pillow 7.98ms · scikit-image 909.1ms
extra peak memory (lower is better)
libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · OpenCV 0.1MB · scikit-image 36.4MB
real-messi5/548x342
time (lower is better)
OpenCV 0.688ms · libstb 1.36ms · libstb (sRGB-correct) 2.70ms · Pillow 5.64ms · scikit-image 667.6ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · libstb (sRGB-correct) 0.0MB · Pillow 0.0MB · scikit-image 26.3MB
Editing

Editing images

Crop, quarter turn, flip, RGB to gray and alpha compositing: the operations libstb added for working on pixels without leaving the library, against Pillow and OpenCV where they have one. Speed is the best of 7 runs; memory is the extra peak RSS of one isolated process per measurement.

crop: the central half of each side

A new, independent image in every library (an OpenCV slice is a view, so it is copied). This is mostly memory bandwidth. 3-channel images only.

libstb is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{libstb}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): OpenCV 1.2×, Pillow 2.1× as long.

libstb needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.006ms · OpenCV 0.010ms · Pillow 0.021ms
gradient/256x256
time (lower is better)
libstb 0.010ms · OpenCV 0.014ms · Pillow 0.027ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
gradient/1024x1024
time (lower is better)
libstb 0.095ms · OpenCV 0.102ms · Pillow 0.136ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
gradient/2048x2048
time (lower is better)
libstb 0.245ms · OpenCV 0.251ms · Pillow 0.337ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
photo/64x64
time (lower is better)
libstb 0.006ms · OpenCV 0.010ms · Pillow 0.021ms
photo/256x256
time (lower is better)
libstb 0.011ms · OpenCV 0.015ms · Pillow 0.027ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
photo/1024x1024
time (lower is better)
libstb 0.068ms · OpenCV 0.071ms · Pillow 0.101ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
photo/2048x2048
time (lower is better)
libstb 0.222ms · OpenCV 0.236ms · Pillow 0.327ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
noise/64x64
time (lower is better)
libstb 0.006ms · OpenCV 0.010ms · Pillow 0.020ms
noise/256x256
time (lower is better)
libstb 0.011ms · OpenCV 0.014ms · Pillow 0.026ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
noise/1024x1024
time (lower is better)
libstb 0.069ms · OpenCV 0.075ms · Pillow 0.103ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
noise/2048x2048
time (lower is better)
libstb 0.233ms · OpenCV 0.239ms · Pillow 0.331ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
real-baboon/512x512
time (lower is better)
libstb 0.023ms · OpenCV 0.027ms · Pillow 0.044ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
real-butterfly/493x356
time (lower is better)
libstb 0.018ms · OpenCV 0.021ms · Pillow 0.036ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
real-fruits/512x480
time (lower is better)
libstb 0.021ms · OpenCV 0.024ms · Pillow 0.040ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
real-home/512x384
time (lower is better)
libstb 0.019ms · OpenCV 0.023ms · Pillow 0.038ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
real-lena/512x512
time (lower is better)
libstb 0.023ms · OpenCV 0.026ms · Pillow 0.042ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB
real-messi5/548x342
time (lower is better)
libstb 0.017ms · OpenCV 0.021ms · Pillow 0.036ms
extra peak memory (lower is better)
libstb 0.0MB · OpenCV 0.0MB · Pillow 0.0MB

rotate: a counter-clockwise quarter turn

Pillow's transpose(ROTATE_90) and cv2.rotate against libstb's rotate90. A turn reads rows and writes columns, so it is about memory access patterns. 3-channel images only.

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 1.2×, Pillow 1.6× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.008ms · OpenCV 0.014ms · Pillow 0.018ms
gradient/256x256
time (lower is better)
OpenCV 0.038ms · libstb 0.047ms · Pillow 0.055ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
gradient/1024x1024
time (lower is better)
OpenCV 0.777ms · libstb 1.05ms · Pillow 1.63ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
gradient/2048x2048
time (lower is better)
libstb 4.25ms · OpenCV 4.96ms · Pillow 5.74ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 4.0MB · libstb 7.6MB
photo/64x64
time (lower is better)
libstb 0.007ms · OpenCV 0.014ms · Pillow 0.018ms
photo/256x256
time (lower is better)
OpenCV 0.039ms · libstb 0.051ms · Pillow 0.058ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
photo/1024x1024
time (lower is better)
OpenCV 0.594ms · libstb 0.760ms · Pillow 1.37ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
photo/2048x2048
time (lower is better)
libstb 3.98ms · OpenCV 4.82ms · Pillow 5.61ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 4.0MB · libstb 7.7MB
noise/64x64
time (lower is better)
libstb 0.008ms · OpenCV 0.014ms · Pillow 0.018ms
noise/256x256
time (lower is better)
OpenCV 0.037ms · libstb 0.046ms · Pillow 0.054ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
noise/1024x1024
time (lower is better)
OpenCV 0.564ms · libstb 0.681ms · Pillow 1.40ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
noise/2048x2048
time (lower is better)
libstb 3.75ms · OpenCV 4.84ms · Pillow 4.96ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 4.0MB · libstb 7.5MB
real-baboon/512x512
time (lower is better)
OpenCV 0.104ms · libstb 0.151ms · Pillow 0.192ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.077ms · Pillow 0.122ms · libstb 0.142ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB
real-fruits/512x480
time (lower is better)
OpenCV 0.107ms · libstb 0.139ms · Pillow 0.156ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-home/512x384
time (lower is better)
OpenCV 0.094ms · libstb 0.142ms · Pillow 0.151ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-lena/512x512
time (lower is better)
OpenCV 0.104ms · libstb 0.171ms · Pillow 0.191ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-messi5/548x342
time (lower is better)
OpenCV 0.087ms · Pillow 0.129ms · libstb 0.139ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB

flip left to right

Pillow's transpose(FLIP_LEFT_RIGHT) and cv2.flip against libstb's flip_horizontal. 3-channel images only.

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 1.4×, Pillow 1.6× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.007ms · OpenCV 0.013ms · Pillow 0.017ms
gradient/256x256
time (lower is better)
OpenCV 0.024ms · libstb 0.034ms · Pillow 0.041ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
gradient/1024x1024
time (lower is better)
OpenCV 0.363ms · Pillow 0.467ms · libstb 0.496ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB
gradient/2048x2048
time (lower is better)
OpenCV 0.916ms · libstb 1.52ms · Pillow 1.69ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 4.0MB · libstb 7.5MB
photo/64x64
time (lower is better)
libstb 0.008ms · OpenCV 0.013ms · Pillow 0.016ms
photo/256x256
time (lower is better)
OpenCV 0.026ms · libstb 0.035ms · Pillow 0.043ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
photo/1024x1024
time (lower is better)
OpenCV 0.253ms · libstb 0.399ms · Pillow 0.410ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
photo/2048x2048
time (lower is better)
OpenCV 0.934ms · libstb 1.49ms · Pillow 1.56ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 4.0MB · libstb 7.6MB
noise/64x64
time (lower is better)
libstb 0.007ms · OpenCV 0.013ms · Pillow 0.017ms
noise/256x256
time (lower is better)
OpenCV 0.025ms · libstb 0.031ms · Pillow 0.041ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
noise/1024x1024
time (lower is better)
OpenCV 0.238ms · libstb 0.394ms · Pillow 0.400ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
noise/2048x2048
time (lower is better)
OpenCV 0.921ms · libstb 1.56ms · Pillow 1.63ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 4.0MB · libstb 7.6MB
real-baboon/512x512
time (lower is better)
OpenCV 0.065ms · libstb 0.114ms · Pillow 0.117ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.048ms · libstb 0.078ms · Pillow 0.084ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-fruits/512x480
time (lower is better)
OpenCV 0.061ms · libstb 0.104ms · Pillow 0.106ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-home/512x384
time (lower is better)
OpenCV 0.067ms · Pillow 0.099ms · libstb 0.102ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB
real-lena/512x512
time (lower is better)
OpenCV 0.065ms · Pillow 0.112ms · libstb 0.113ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB
real-messi5/548x342
time (lower is better)
OpenCV 0.049ms · libstb 0.080ms · Pillow 0.085ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB

convert: RGB to gray

libstb and Pillow use the same integer formula and give identical pixels; OpenCV's BGR2GRAY rounds slightly differently. libstb runs the fastest SIMD backend of the CPU it is measured on (libstb.simd_name()). 3-channel images only.

OpenCV is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{OpenCV}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): libstb 1.2×, Pillow 1.7× as long.

OpenCV needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured).

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (18 corpus entries)
gradient/64x64
time (lower is better)
libstb 0.008ms · OpenCV 0.014ms · Pillow 0.021ms
gradient/256x256
time (lower is better)
OpenCV 0.033ms · libstb 0.036ms · Pillow 0.055ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
gradient/1024x1024
time (lower is better)
OpenCV 0.372ms · Pillow 0.628ms · libstb 0.701ms
extra peak memory (lower is better)
OpenCV 0.0MB · Pillow 0.0MB · libstb 0.0MB
gradient/2048x2048
time (lower is better)
OpenCV 1.26ms · libstb 1.80ms · Pillow 2.30ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
photo/64x64
time (lower is better)
libstb 0.008ms · OpenCV 0.013ms · Pillow 0.020ms
photo/256x256
time (lower is better)
OpenCV 0.034ms · libstb 0.041ms · Pillow 0.055ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
photo/1024x1024
time (lower is better)
OpenCV 0.327ms · libstb 0.452ms · Pillow 0.555ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
photo/2048x2048
time (lower is better)
OpenCV 1.26ms · libstb 1.75ms · Pillow 2.15ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
noise/64x64
time (lower is better)
libstb 0.008ms · OpenCV 0.013ms · Pillow 0.020ms
noise/256x256
time (lower is better)
OpenCV 0.031ms · libstb 0.036ms · Pillow 0.054ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
noise/1024x1024
time (lower is better)
OpenCV 0.333ms · libstb 0.444ms · Pillow 0.550ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
noise/2048x2048
time (lower is better)
OpenCV 1.21ms · libstb 1.77ms · Pillow 2.19ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-baboon/512x512
time (lower is better)
OpenCV 0.094ms · libstb 0.121ms · Pillow 0.175ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-butterfly/493x356
time (lower is better)
OpenCV 0.067ms · libstb 0.085ms · Pillow 0.122ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-fruits/512x480
time (lower is better)
OpenCV 0.085ms · libstb 0.109ms · Pillow 0.144ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-home/512x384
time (lower is better)
OpenCV 0.076ms · libstb 0.096ms · Pillow 0.175ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-lena/512x512
time (lower is better)
OpenCV 0.091ms · libstb 0.116ms · Pillow 0.155ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB
real-messi5/548x342
time (lower is better)
OpenCV 0.069ms · libstb 0.086ms · Pillow 0.110ms
extra peak memory (lower is better)
OpenCV 0.0MB · libstb 0.0MB · Pillow 0.0MB

composite: RGBA over RGBA, straight alpha

An RGBA image laid over its own upside-down copy, against Pillow's Image.alpha_composite (OpenCV has no equivalent). The alpha channel is identical; the colour is within one level where the pixel is visible. 4-channel images only, so only the graphics images take part.

libstb is the reference (fastest on the most corpus entries). On average (\(\mathbb{E}\!\left[\dfrac{t_{L}}{t_{\text{libstb}}}\right]\), the mean of each entry's own ratio, not a ratio of medians): Pillow 2.6× as long.

libstb needs the least extra memory on the most entries (extra peak RSS on top of what the process held before the operation started; images under 0.065 MP are not measured). On average, \(\mathbb{E}\!\left[\dfrac{m_{L}}{m_{\text{libstb}}}\right]\): Pillow 1.0× as much.

Throughput vs. image size (higher is better)

Time vs. image size (lower is better)

Extra peak memory vs. image size (lower is better)

See per-entry detail (4 corpus entries)
graphics/64x64
time (lower is better)
libstb 0.012ms · Pillow 0.031ms
graphics/256x256
time (lower is better)
libstb 0.178ms · Pillow 0.266ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB
graphics/1024x1024
time (lower is better)
libstb 1.29ms · Pillow 4.09ms
extra peak memory (lower is better)
libstb 0.0MB · Pillow 0.0MB
graphics/2048x2048
time (lower is better)
libstb 5.46ms · Pillow 16.4ms
extra peak memory (lower is better)
Pillow 16.0MB · libstb 16.1MB
Scaling

Does the slope change with image size?

One photo-like image at each side length from 128 to 4096 pixels, one representative operation of each kind, libstb against Pillow and OpenCV. A flat line means the cost per pixel stays constant; a falling line means it grows with the image.

decode PNG (throughput, higher is better)

decode JPEG (throughput, higher is better)

encode PNG (throughput, higher is better)

encode JPEG (throughput, higher is better)

resize, half size, cubic (throughput, higher is better)

Text

stb_truetype vs. FreeType

DejaVuSans.ttf, libstb's Font against Pillow's FreeType binding on its basic layout engine (so Pillow is not charged for shaping, which stb_truetype does not do). The two rasterize differently, so this compares speed only. stb_truetype has no security guarantee on untrusted fonts; FreeType is hardened. No speed number captures that.

open: load the font file, get a font object

On average (\(\mathbb{E}\!\left[\dfrac{t_{\text{libstb}}}{t_{\text{Pillow}}}\right]\), the mean of each case's own ratio): 0.48×; below 1 means libstb took less time.

Time per call (lower is better)

See the numbers
CaselibstbPillowlibstb / Pillow
16px24.1µs66.2µs0.36×
32px32.7µs67.4µs0.48×
64px32.2µs55.6µs0.58×

measure: how big would this text be

On average (\(\mathbb{E}\!\left[\dfrac{t_{\text{libstb}}}{t_{\text{Pillow}}}\right]\), the mean of each case's own ratio): 0.07×; below 1 means libstb took less time.

Time per call (lower is better)

See the numbers
CaselibstbPillowlibstb / Pillow
short 16px9.9µs83.1µs0.12×
short 32px9.7µs84.0µs0.12×
short 64px7.5µs85.4µs0.09×
paragraph 16px16.9µs814.8µs0.02×
paragraph 32px20.7µs775.3µs0.03×
paragraph 64px20.7µs788.0µs0.03×

render: text in, coverage bitmap out (measure + allocate + draw)

On average (\(\mathbb{E}\!\left[\dfrac{t_{\text{libstb}}}{t_{\text{Pillow}}}\right]\), the mean of each case's own ratio): 0.10×; below 1 means libstb took less time.

Time per call (lower is better)

See the numbers
CaselibstbPillowlibstb / Pillow
short 16px35.4µs277.8µs0.13×
short 32px41.5µs293.4µs0.14×
short 64px61.6µs366.1µs0.17×
paragraph 16px101.9µs2.57ms0.04×
paragraph 32px143.7µs2.91ms0.05×
paragraph 64px244.5µs3.70ms0.07×
Environment

Where these numbers came from

Before anything was timed, every operation and library was run on small non-square images and its output checked (exact pixels for lossless formats, close for JPEG and resizing): 225 checks passed, 0 failed, 11 library/operation pairs unavailable (formats a library cannot handle at all).

CPUIntel(R) Xeon(R) Processor
Logical cores1
RAM3.9 GiB
Architecturex86_64
OSLinux 6.18.44-fc-v114
PythonCPython 3.12.3