imageflow
High-performance image manipulation for web servers. Includes imageflow_server, imageflow_tool, and libimageflow
Top Related Projects
A fast image processing library with low memory needs.
High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
Fast, simple, scalable, Docker-ready HTTP microservice for high-level image processing
thumbor is an open-source photo thumbnail service by globo.com
A caching, resizing image proxy written in Go
Fast and secure standalone server for resizing and converting remote images
Quick Overview
Imageflow is a high-performance image processing library and server designed for web applications. It focuses on providing fast, efficient, and secure image resizing and optimization capabilities, with a strong emphasis on security and performance.
Pros
- High-performance image processing with a focus on speed and efficiency
- Comprehensive security measures to prevent common vulnerabilities
- Cross-platform support (Windows, macOS, Linux)
- Offers both a library and a server component for flexible integration
Cons
- Limited documentation and examples compared to some more established image processing libraries
- Relatively new project, which may lead to potential stability issues or frequent changes
- Smaller community compared to more popular image processing solutions
- Limited language bindings (primarily Rust and C)
Code Examples
- Resizing an image:
use imageflow_core::Context;
let mut c = Context::new()?;
let input = c.read_file("input.jpg")?;
let output = c.create_output_buffer()?;
c.command_chain()
.add_command(|b| b.decode(input))
.add_command(|b| b.resize(400, 300))
.add_command(|b| b.encode_jpeg(output, 80))
.execute()?;
c.write_output_buffer_to_file(output, "output.jpg")?;
- Applying a watermark:
use imageflow_core::Context;
let mut c = Context::new()?;
let input = c.read_file("input.jpg")?;
let watermark = c.read_file("watermark.png")?;
let output = c.create_output_buffer()?;
c.command_chain()
.add_command(|b| b.decode(input))
.add_command(|b| b.constrain_within(800, 600))
.add_command(|b| b.watermark(watermark, 0.8, 10, 10))
.add_command(|b| b.encode_png(output))
.execute()?;
c.write_output_buffer_to_file(output, "output_watermarked.png")?;
- Converting image format:
use imageflow_core::Context;
let mut c = Context::new()?;
let input = c.read_file("input.png")?;
let output = c.create_output_buffer()?;
c.command_chain()
.add_command(|b| b.decode(input))
.add_command(|b| b.encode_webp(output, 90))
.execute()?;
c.write_output_buffer_to_file(output, "output.webp")?;
Getting Started
To get started with Imageflow, follow these steps:
-
Add Imageflow to your Rust project's
Cargo.toml
:[dependencies] imageflow_core = "0.9.0"
-
Import and use Imageflow in your Rust code:
use imageflow_core::Context; fn main() -> Result<(), Box<dyn std::error::Error>> { let mut c = Context::new()?; // Use Imageflow commands here Ok(()) }
-
Run your Rust program to process images using Imageflow.
Competitor Comparisons
A fast image processing library with low memory needs.
Pros of libvips
- Mature and well-established project with a large user base
- Supports a wide range of image formats and operations
- Highly optimized for performance and memory efficiency
Cons of libvips
- Steeper learning curve due to its extensive API
- Less focus on web-specific use cases compared to Imageflow
- C-based core may be less accessible for some developers
Code Comparison
libvips
VipsImage *in, *out;
vips_jpegload("input.jpg", &in, NULL);
vips_resize(in, &out, 0.5, NULL);
vips_jpegsave(out, "output.jpg", NULL);
Imageflow
let mut c = Context::new();
c.execute(Command::build()
.load_file("input.jpg")
.constrain_within(800, 600)
.encode_file("output.jpg", EncoderPreset::mozjpeg()))?;
Summary
libvips is a powerful and versatile image processing library with a long history and broad format support. It excels in performance and offers a wide range of operations. However, it may have a steeper learning curve and is less focused on web-specific use cases compared to Imageflow. The code comparison shows that libvips uses a more traditional C-style API, while Imageflow offers a more modern, fluent interface in Rust.
High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
Pros of Sharp
- More mature project with a larger community and better documentation
- Supports a wider range of image formats and operations
- Faster processing for certain operations, especially on Node.js
Cons of Sharp
- Larger installation size due to libvips dependency
- Less focus on security and memory safety compared to Imageflow
- More complex API for some operations
Code Comparison
Sharp:
sharp(inputBuffer)
.resize(300, 200)
.toFormat('webp')
.toBuffer((err, buffer) => {
// Handle result
});
Imageflow:
imageflow.Job.create()
.decode(inputBuffer)
.resizeTo(300, 200)
.encode({ format: 'webp' })
.run()
.then(result => {
// Handle result
});
Both Sharp and Imageflow are powerful image processing libraries for Node.js, but they have different strengths and approaches. Sharp is more established and feature-rich, while Imageflow focuses on security and memory safety. The choice between them depends on specific project requirements, performance needs, and development priorities.
Fast, simple, scalable, Docker-ready HTTP microservice for high-level image processing
Pros of Imaginary
- Written in Go, offering good performance and easy deployment
- Supports a wide range of image processing operations
- Provides a simple HTTP API for easy integration
Cons of Imaginary
- Limited to image processing operations only
- Lacks advanced features like face detection or content-aware resizing
Code Comparison
Imageflow (C):
Image *image = Image_create_from_file("input.jpg");
Image_scale(image, 800, 600, ScaleMode_Max);
Image_save_to_file(image, "output.jpg");
Imaginary (Go):
resp, err := http.Get("http://localhost:8088/resize?width=800&height=600&file=input.jpg")
if err != nil {
// Handle error
}
Summary
Imageflow is a comprehensive image processing library written in C, offering high performance and a wide range of features. It provides both a C API and HTTP server options.
Imaginary is a simpler, Go-based image processing service that focuses on providing a straightforward HTTP API for common image operations. It's easier to deploy and integrate but may lack some advanced features found in Imageflow.
Both projects aim to simplify image processing tasks, but they cater to different use cases and development preferences. Imageflow is better suited for projects requiring extensive image manipulation capabilities, while Imaginary is ideal for quick integration of basic image processing functionality through a REST API.
thumbor is an open-source photo thumbnail service by globo.com
Pros of Thumbor
- Written in Python, making it accessible to a wider range of developers
- Extensive feature set, including face detection and smart cropping
- Large and active community with frequent updates
Cons of Thumbor
- Generally slower performance compared to Imageflow
- Higher resource consumption, especially for memory-intensive operations
- More complex setup and configuration process
Code Comparison
Thumbor (Python):
from thumbor.url_signers import BaseUrlSigner
class MyUrlSigner(BaseUrlSigner):
def signature(self, url):
return hmac.new(self.security_key, url.encode('utf-8'), hashlib.sha1).hexdigest()
Imageflow (Rust):
use imageflow_core::Context;
let mut c = Context::new()?;
c.configure_operation(Operation::Decode)?
.configure_operation(Operation::Constrain { w: 800, h: 600, mode: ConstraintMode::Within })?
.configure_operation(Operation::Encode { format: ImageFormat::Jpeg, quality: 90 })?;
The code snippets demonstrate the different approaches to image processing in each library. Thumbor uses a more high-level, Python-based approach, while Imageflow leverages Rust's performance and type safety for efficient image manipulation.
A caching, resizing image proxy written in Go
Pros of imageproxy
- Written in Go, offering good performance and easy deployment
- Supports multiple image processing operations (resize, crop, rotate, etc.)
- Can fetch images from various sources (local, remote, S3)
Cons of imageproxy
- Limited advanced image processing features compared to Imageflow
- May not be as optimized for high-volume image processing tasks
- Lacks some of the more sophisticated algorithms found in Imageflow
Code Comparison
imageproxy:
func (t *Transform) String() string {
parts := make([]string, 0, 5)
if t.Width > 0 || t.Height > 0 {
parts = append(parts, fmt.Sprintf("%dx%d", t.Width, t.Height))
}
// ... (additional code)
}
Imageflow:
pub fn resize_image_aspect(
ctx: &mut Context,
input: &InputBuffer,
w: i32,
h: i32,
fit: ResampleFilter,
) -> Result<Vec<u8>> {
// ... (implementation details)
}
The code snippets show different approaches to image transformation. imageproxy uses a string-based representation for transformations, while Imageflow provides more granular control through specific function calls and parameters.
Fast and secure standalone server for resizing and converting remote images
Pros of imgproxy
- Written in Go, offering good performance and easy deployment
- Supports a wide range of image processing operations
- Provides a simple URL-based API for image transformations
Cons of imgproxy
- Limited advanced features compared to Imageflow
- May require more manual configuration for complex use cases
- Less focus on image optimization and compression
Code Comparison
Imageflow (Rust):
let mut c = Context::create()?;
let mut b = c.build_command()?;
b.add_step("decode")?
.constrain_within(500, 500)?
.encode_jpeg(80)?;
imgproxy (Go):
options := imgproxy.Options{
Width: 500,
Height: 500,
Format: imgproxy.FormatJPEG,
Quality: 80,
}
url := imgproxy.BuildURL(sourceURL, options)
Both libraries offer straightforward APIs for basic image processing tasks. Imageflow provides a more granular approach with its step-based pipeline, while imgproxy uses a simpler options-based configuration.
Imageflow focuses on high-performance image processing with advanced features, while imgproxy prioritizes ease of use and quick deployment for common image transformation tasks.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
optimal images at incredible speeds
Download blazing fast and safer tools for a modern image workflow.
imageflow_tool
is a command-line tool for experimenting, running batch jobs, JSON jobs, or when you want process isolation. Up to 17x faster than ImageMagick. Also produces smaller files at higher quality. Download ordocker run imazen/imageflow_tool
.libimageflow
is for direct (in-process) use from your programming language. See our Node bindings, Go bindings, Scala bindings, Elixir bindings, or .NET bindings. If we don't already have bindings for your language, consider spending a day to add them. Imageflow has a simple C-compatible ABI, of which only 4 methods are needed to implement bindings.- Imageflow.Server is cross-platform and can manipulate images in-flight (e.g.
/bucket/img.jpg?w=200
) for direct use from HTML. Source images can reside in blob storage, on another server, or on the filesystem. It's a production ready server with excellent hybrid disk caching, support for Azure and Amazon blob storage, and can be easily customized. You can deploy it easily via Docker, on a VM, or via any cloud host. It's also backwards compatible with the ImageResizer API - which is useful, as ImageResizer as been integrated into more than a thousand different CMSes and applications in the last decade.
Open an issue to share ideas, feedback, or ask questions. We believe in feedback-driven design, and streamlining real-world usage is the fastest way to a great product.
libimageflow and imageflow_tool are available as self-contained binaries for Windows, Ubuntu, and Mac. We also offer Docker images for Linux (where glibc and OpenSSL are required).
We thank our backers on Kickstarter and the many supporters of ImageResizer for making this project a reality. Visit Imageresizing.net if you need an AGPLv3 exception for commercial use.
Start with imageflow_tool (recommended)
imageflow_tool examples --generate
- creates an examples directory with JSON jobs and invocation scripts.
You can use command strings that are compatible with ImageResizer 4 querystrings:
imageflow_tool v1/querystring --in source.jpg --out thumb.jpg --command "width=50&height=50&mode=crop&format=jpg"
Or submit a JSON job file. JSON jobs can have multiple inputs and outputs, and can represent any kind of operation graph.
The following generates multiple sizes of an image from an example job file:
imageflow_tool v1/build --json examples/export_4_sizes/export_4_sizes.json
--in waterhouse.jpg
--out 1 waterhouse_w1600.jpg
2 waterhouse_w1200.jpg
3 waterhouse_w800.jpg
4 waterhouse_w400.jpg
--response operation_result.json
By default, imageflow_tool prints a JSON response to stdout. You write this to disk with --response
.
--debug-package
will create a .zip file to reproduce problematic behavior with both v1/build
and v1/querystring
. Please submit bug reports; we try to make it easy.
Using Imageflow.Server for dynamic imaging
NOTE: imageflow_server has been removed as the underlying web framework (iron) is abandoned and no longer secure. For the last few years we have suggested moving to the production-ready Imageflow.Server product, which also offers docker deployment (but we suggest your own dockerfile to permit configuration)
Now you can edit images from HTML... and use srcset without headache.
<img src="http://localhost:39876/demo_images/u3.jpg?w=300" />
<img src="" srcset=" http://localhost:39876/demo_images/u3.jpg?w=300 300w
http://localhost:39876/demo_images/u3.jpg?w=800 800w
http://localhost:39876/demo_images/u3.jpg?w=1600 1600w" />
Using libimageflow from your language
- .NET Standard bindings can be found at https://github.com/imazen/imageflow-dotnet
- Node bindings available at https://github.com/imazen/imageflow-node
- Ruby - Basic bindings can be found in bindings/ruby/
- C and C++ interface is stable - use bindings/headers/imageflow_default.h or one of the many alternate conventions provided with each release.
- Rust - Imageflow is written in Rust, so you can use the
imageflow_core
crate, althogh the interfaces are not stable or semver in line with tagged releases (those version numbers are for the C ABI, not the Rust API) - other languages - Use an FFI binding-generation tool for your language, and feed it whichever header file it likes best.
You also may find that imageflow_tool
is quite fast enough for your needs.
Crates within this project
- imageflow_abi - The stable API of libimageflow/imageflow.dll.
Headers for libimageflow are located in
bindings/headers
- imageflow_tool - The command-line tool
- c_components - A rust crate containing C source
- c_components/tests - Tests for the C components
- imageflow_types - Shared types used by most crates, with JSON serialization
- imageflow_helpers - Common helper functions and utilities
- imageflow_riapi - RIAPI and ImageResizer4 compatibility parsing/layout
- imageflow_core - The main library and execution engine
Building from Source without Docker
You'll need more than just Rust to compile Imageflow, as it has a couple C dependencies.
-
Install platform-specific prerequisites (find the right section below).
-
Clone and cd into this repository E.g.,
git clone git@github.com:imazen/imageflow.git && cd imageflow
) -
Run
cargo build --release --all
-
Look in
./target/release
for the binaries
If you are on Windows, only run build commands in the window created by win_enter_env.bat
.
Build using cargo
directly, although this will place binaries in ./target/release
instead.
* `cargo test --all` to test Imageflow in debug (slooow) mode
* `cargo build --package imageflow_abi --release` to compile `libimageflow/imageflow.dll`
* `cargo build --package imageflow_tool --release` to compile `imageflow_tool(.exe)`
* `cargo build --all --release` to compile everything in release mode
* `cargo doc --no-deps --all --release` to generate documentation.
Linux Pre-requisites
(tested on Ubuntu 20.04 and 22.04.)
#Install Rust by running
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable
#Ensure build tools are installed (git, curl, wget, gcc, g++, nasm, pkg-config, openssl, ca-certificates)
sudo apt-get install --no-install-recommends -y \
sudo build-essential nasm dh-autoreconf pkg-config ca-certificates \
git zip curl libpng-dev libssl-dev wget libc6-dbg \
libcurl4-openssl-dev libelf-dev libdw-dev apt-transport-https
Mac OS Pre-requisites
- Install XCode Command-Line Tools if you haven't already
- Install Homebrew if you haven't already.
- Install nasm, pkg-config, and wget
brew install nasm pkg-config wget
- Install Rust
Windows WSL (Ubuntu) Pre-requisites
- Install Ubuntu from the Windows Store
- Run Ubuntu 22.04 and create your username/password
sudo apt-get update
to update available packages.- Install Rust by running
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable
- Ensure build tools are installed (git, curl, wget, gcc, g++, nasm, pkg-config, openssl, ca-certificates)
sudo apt-get install git wget curl build-essential pkg-config libssl-dev libpng-dev nasm
- (optional) To use a graphical text editor, you'll need to download imageflow to a "Windows" directory, then map it to a location in Ubuntu.
For example, if you cloned imageflow to Documents/imageflow, you would run:
ln -s /mnt/c/Users/[YourWindowsUserName]/Documents/imageflow ~/win_imageflow
- Close and re-open Ubuntu
Windows 10 Pre-requisites
- Install Visual Studio 2017 Build Tools (separately or as a VS component)
- Install Git 64-bit.
Run As Administrator
the NASM 64-bit installer - it will not prompt.- Install Rust 64-bit if you want 64-bit Imageflow or Rust 32-bit if you don't.
Install toolchain
stable
as the default, and confirm adding it toPATH
. - Open the command line and switch to this repository's root directory
- Edit
ci/wintools/SETUP_PATH.bat
to ensure that rust/cargo, nasm, git, and Git/mingw64/bin are all in%PATH%
. - Run
win_enter_env.bat
to start a sub-shell (edit it if you want a 32-bit build) - All build commands should be run in the sub-shell. Run
cmd.exe /c "ci\wintools\win_verify_tools.bat"
to check tools are present.
How does one learn image processing for the web?
First, read High Performance Images for context.
There are not many great textbooks on the subject. Here are some from my personal bookshelf. Between them (and Wikipedia) I was able to put together about 60% of the knowledge I needed; the rest I found by reading the source code to many popular image processing libraries.
I would start by reading Principles of Digital Image Processing: Core Algorithms front-to-back, then Digital Image Warping. Wikipedia is also a useful reference, although the relevant pages are not linked or categorized together - use specific search terms, like "bilinear interpolation" and "Lab color space".
- Digital Image Warping
- Computer Graphics: Principles and Practice in C (2nd Edition)
- Principles of Digital Image Processing: Fundamental Techniques
- Principles of Digital Image Processing: Core Algorithms
- Principles of Digital Image Processing: Advanced Methods
I have found the source code for OpenCV, LibGD, FreeImage, Libvips, Pixman, Cairo, ImageMagick, stb_image, Skia, and FrameWave is very useful for understanding real-world implementations and considerations. Most textbooks assume an infinite plane, ignore off-by-one errors, floating-point limitations, color space accuracy, and operational symmetry within a bounded region. I cannot recommend any textbook as an accurate reference, only as a conceptual starting point. I made some notes regarding issues to be aware of when creating an imaging library.
Also, keep in mind that computer vision is very different from image creation. In computer vision, resampling accuracy matters very little, for example. But in image creation, you are serving images to photographers, people with far keener visual perception than the average developer. The images produced will be rendered side-by-side with other CSS and images, and the least significant bit of inaccuracy is quite visible. You are competing with Lightroom; with offline tools that produce visually perfect results. End-user software will be discarded if photographers feel it is corrupting their work.
Top Related Projects
A fast image processing library with low memory needs.
High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
Fast, simple, scalable, Docker-ready HTTP microservice for high-level image processing
thumbor is an open-source photo thumbnail service by globo.com
A caching, resizing image proxy written in Go
Fast and secure standalone server for resizing and converting remote images
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot