Library / SDK
image-rs/imageproc avatar
image-rs/imageproc

imageproc: image processing operations for Rust, built on the image crate

Image processing operations

986 stars181 forksRustMIT

At a glance

What is it?
imageproc is a Rust library of image processing operations layered on the image crate, with feature flags for rayon parallelism, text drawing and frequency domain functions, and a stated goal of being a consistent basis for computer vision work or graphics editors. It assumes linear colour, and its manifest sits one version ahead of its last release.
Who is it for?
imageproc is the right choice if you are writing Rust and want proven building blocks for filters, drawing and matching rather than a collection of format converters, and if you can live with the linear colour assumption. It is the wrong choice if your pipeline is built around sRGB files with no conversion step, if you need exotic file formats or higher dimensional images, or if you want a windowing feature without installing SDL2 first.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 22 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the library covers, and what it refuses to cover

imageproc is a Rust library of image processing operations, built on top of the image crate, and its stated goals are narrow on purpose: a performant, well tested, well documented library with a consistent API, suitable as the basis of computer vision applications or graphics editors. The non-goals are stated just as precisely. Maximum genericity over image storages or formats is not a goal, and neither is support for higher-dimensional images. That second decision has consequences, because a lot of modern vision work is done on volumes and on multi channel arrays rather than on flat images, and this library will not cover that case. The first decision is the more useful one. Rather than trying to be the crate that opens every format, imageproc assumes the image crate has already decoded your pixels, which means the operations can share one buffer type and one consistent signature style, and the format handling stays where it belongs. The API documentation is published on docs.rs, and the crate is on crates.io.

Everything assumes linear colour, and that is the sharpest edge

The readme puts a colour space section near the top, and it deserves attention before any other. Functions in this library implicitly assume that pixel colours are stored in a linear colour space like RGB, as opposed to a non-linear colour space such as sRGB. The readme links an article on gamma correction that introduces the topic and shows the colour artefacts that result from not using linear colour spaces. In practice this means the library is doing arithmetic in a space where a value of 128 is half the light, while a file saved in sRGB stores 128 as a distinctly brighter value. Filters, blends and gradients all inherit that assumption, so feeding the library sRGB data produces results that are subtly wrong rather than obviously broken, and the error is easy to miss because the output still looks like an image. If your pipeline reads JPEG or PNG files straight from disk, you need a conversion step to linear before processing, and ideally back to sRGB after. This is the one piece of advice that would change the outcome of most projects that get imageproc results wrong.

The same operation, single threaded and on rayon

The library provides both single threaded and multi threaded variations of several functions, using rayon for the parallel versions. The structure is the same throughout, so a caller picks the variant that fits and the semantics do not change. The readme is careful about the claim, and so should you be: depending on the image size and the amount of work performed per pixel, the parallel versions may not always be faster, and the recommendation is to benchmark for your specific use case. That caveat is more than boilerplate, because the cost of spinning up a rayon thread pool is fixed while the work per pixel varies, so a large filter on a small image can be slower in parallel than the same filter on a large one. The rayon feature is on by default, along with text drawing and the frequency domain functions, which means the parallel code path is what you get unless you turn it off. If you are writing a library on top of imageproc rather than an application, disabling the feature lets your users choose.

Feature flags decide what gets compiled in

The default feature set is rayon for the multi-threaded variants, text for drawing, and fft for phash and other functions that depend on the fast Fourier transform crate. Three optional dependencies back those. text pulls in ab_glyph for font rendering, fft pulls in a discrete cosine transform crate, and the display-window feature pulls in sdl2, which lets you show images through the imageproc::window module. The display feature has a system requirement worth knowing before you enable it, since SDL2 must be installed on the system before building with the feature:

bash
# Ubuntu/Debian
sudo apt install libsdl2-dev

# macOS
brew install sdl2

On Windows the instruction is to install SDL2 and make sure its library directory is available to the linker and its DLL directory is included in PATH. The manifest shows the feature graph plainly:

toml
[features]
default = ["rayon", "image/default", "text", "fft"]
display-window = ["sdl2"]
rayon = ["dep:rayon", "image/rayon"]
fft = ["dep:rustdct"]
text = ["dep:ab_glyph"]

One detail there is worth a second look. The readme describes the fft feature as enabling functions that depend on the rustfft crate, while the manifest wires the feature to the rustdct dependency, so the readme and the manifest do not name the same crate. Whichever one is right, the feature flag is the stable part of the contract.

The manifest is one version ahead of the published crate

The version numbers in the repository tell you where the project is. The manifest declares version 0.28.0, while the most recent published release is v0.27.0 from 2026-06-02, with v0.26.1 in February and v0.26.0 in January before it. The tree is therefore sitting on an unreleased version, which is normal for a project with a steady commit rate but matters if you depend on the crate from crates.io rather than from a git reference, because your build gets v0.27.0 and not what you see in the repository. The rest of the manifest is modern Rust: edition 2024 with a minimum supported Rust version of 1.87.0, MIT licensed, and dependencies pinned to specific major lines for image, nalgebra, itertools, rand and rand_distr. Two dependencies are worth noting for planning. katexit is optional and is the one the docs.rs metadata enables, and the metadata has the all-features line commented out with a reference to an issue in the tracker, which suggests the maintainers hit a problem building the documentation with every feature on. There is also a wasm32 target section that pulls in getrandom with its wasm_js feature, so the library is intended to compile for the browser.

The examples directory is the real API tour

The examples folder is unusually broad, and the file names describe the scope of the library better than any feature list would. There are bilateral filtering, general blending, a brief demonstration, colour effects, drawing, font rendering, gradients, the histogram of oriented gradients, Hough transform, projection, seam carving and template matching, plus a pair of image display examples that use the SDL2 backed window. Two sample images and a DejaVuSans.ttf font file come with them, so the examples are runnable rather than illustrative. Several of these are also the algorithms you would otherwise reach for a computer vision crate to get: the histogram of oriented gradients and the Hough transform are the classic pairing for shape detection, template matching is what you want for finding a logo in a screenshot, and seam carving is the resizing algorithm that preserves content. The point for an adopter is that the examples double as a catalogue of what the library can already do, so before you write a filter it is worth checking whether the operation is already an example file.

Property based testing and a browser test target

The development dependencies say something about how the library is checked. Beyond the usual assert_approx_eq for floating point comparisons, the project pulls in proptest, which generates random inputs and checks that invariants hold, the right tool for image code where the interesting bugs live in the boundaries, on tiny images and extreme coordinates. wasm-bindgen-test is also a dev dependency, matching the wasm32 target section in the manifest, which means the library is not only expected to compile for the browser but is expected to be testable there. Coverage is tracked through coveralls with a badge in the readme, and the dependency status badge on deps.rs will show whether the pinned versions of the underlying crates have moved on. The repository also carries flake.nix and flake.lock for reproducible development environments, a CHANGELOG.md, a CONTRIBUTING.md, and a .cargo directory for cargo configuration. Together those point at a project with a serious process around a small, focused library.

Editorial conclusion

imageproc is the right choice if you are writing Rust and want proven building blocks for filters, drawing and matching rather than a collection of format converters, and if you can live with the linear colour assumption. It is the wrong choice if your pipeline is built around sRGB files with no conversion step, if you need exotic file formats or higher dimensional images, or if you want a windowing feature without installing SDL2 first. Before you start, decide whether your pixel data is linear, benchmark the rayon variant rather than assuming it wins, and note that the manifest is at 0.28.0 while the last published crate is v0.27.0, so pin the version you actually test.

Frequently asked questions

What is imageproc?

imageproc is a Rust library of image processing operations built on the image crate, with a goal of providing a consistent API suitable as the basis of computer vision applications or graphics editors. It explicitly does not aim for genericity over image formats or for higher-dimensional images.

Does imageproc work with sRGB images?

The functions implicitly assume a linear colour space such as RGB rather than a non-linear one like sRGB, and the readme links an introduction to gamma correction that shows the artefacts caused by getting this wrong. You need to convert to linear before processing.

Is the rayon version of an imageproc function always faster?

No. The library provides single threaded and rayon based versions of several functions, but the readme notes that depending on image size and work per pixel the parallel versions may not always be faster, and recommends benchmarking for your own use case.

What do I need to build imageproc with the display window feature?

The display-window feature enables imageproc::window through SDL2, and SDL2 must be installed on the system first. On Ubuntu and Debian that means sudo apt install libsdl2-dev, on macOS brew install sdl2, and on Windows you must add the SDL2 library directory to the linker path and its DLL directory to PATH.

Which Rust version does imageproc require?

The manifest sets a minimum supported Rust version of 1.87.0 and uses edition 2024. The crate is MIT licensed and published on crates.io as imageproc.

Official sources

  1. image-rs/imageproc on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/image-rs-imageproc.svg)](https://hysenlabs.com/projects/image-rs-imageproc)

Was this useful?