更新项目 imazen/imageflow

imageflow optimal images at incredible speeds

travis-master AppVeyor build status Coverity Scan Build Status state: technical preview

  • imageflow_server can run jobs or 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.
  • libimageflow is for direct (in-process) use from your programming language. It has a simple C-compatible ABI and bindings.
  • imageflow_tool is a command-line tool for experimenting, running batch jobs, or when you want process isolation. Up to 17x faster than ImageMagick.

These all offer the JSON /build API as well as the traditional width=300&height=200&mode=crop&format=jpg command string form. Each is available as a self-contained binary for Windows and Mac. We offer Docker images for Linux (where glibc and OpenSSL are required).

libimageflow offers interactive job manipulation as well like /tell_decoder, /get_image_info, and /execute. Unless you are using memory buffers for I/O, it's better to use /build.

view releases or docker run --rm imazen/imageflow_tool

We thank our backers on Kickstarter and the many supporters of ImageResizer for making this project a reality. Email support@imageflow.io if you need an AGPLv3 exception for commercial use.

Also, please send us 'challenging' images and tasks. We'd also appreciate it if you'd explore the JSON APIs and review them and other topics where we are requesting feedback. And – we need help with benchmarking on Windows.

If we enough people beta-test Imageflow and provide feedback, we aim to publish a stable 1.0 release in August 2017 (along with Ruby and Node bindings). See flaws and missing features for project status.

Using imageflow_tool

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 v0.1/ir4 --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 v0.1/build --json examples/export_4_sizes/export_4_sizes.json
        --in http://s3-us-west-2.amazonaws.com/imageflow-resources/test_inputs/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 v0.1/build and v0.1/ir4. Please submit bug reports; we try to make it easy.

Using imageflow_server for dynamic imaging

imageflow_server start --demo

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" />

Beyond the demo

You'll want to mount various image source locations to prefixes. The --mount command parses a colon (:) delimited list of arguments. The first is the prefix you'll use in the URL (like http://localhost:39876/prefix/. The second is the engine name. Remaining arguments are sent to the engine.

Examples

  • --mount "/img/:ir4_local:C:\inetpub\wwwroot\images"
  • --mount "/proxyimg/:ir4_http:https:://myotherserver.com/imagefolder/" (note the double escaping of the colon)
  • --mount "/cachedstaticproxy/:permacache_proxy:https:://othersite.com"
  • --mount "/githubproxy/:permacache_proxy_guess_content_types:https:://raw.github.com/because/it/doesnt/support/content/types"
  • --mount "/static/":static:./assets"

Using libimageflow

Official Ruby and Node bindings will be released by August 2017.

How to build Imageflow from source

We're assuming you've cloned already.

     git clone git@github.com:imazen/imageflow.git
     cd imageflow

Docker (linux/macOS/WinUbuntu)

This will create caches within ~/.docker_imageflow_caches specific to the docker image used. Instances will be ephemeral; the only state will be in the caches.

./build_via_docker.sh debug

Linux (native)

We need a few packages in order to build the C dependencies. You probably have most of these already.

  • build-essential, nasm, pkg-config
  • wget, curl, git
  • libpng, libssl, ca-certificates

For Ubuntu 14.04 and 16.04:

sudo apt-get install --no-install-recommends \
  build-essential nasm pkg-config \
  wget curl git ca-certificates \
  libpng-dev libssl-dev

After installing the above, you'll need dssim, and Rust Nightly.

curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly-2018-04-04
./ci/nixtools/install_dssim.sh
./build.sh

We aren't listing dependencies needed for

  • Valgrind (common versions break openssl; you may need to build from source)
  • Code coverage
  • Bindings.

Please consult the official Dockerfiles for these.

OS X (native)

You'll need a bit less on OS X, although this may not be comprehensive:

brew install nasm libpng pkg-config wget
./ci/nixtools/install_dssim.sh
./build.sh

Windows

Pre-requisites

  1. Visual Studio 2015 or 2017 (Only the C++ Build Tools component is required)
  2. Install Git 64-bit.
  3. Install NASM 64-bit Installer must be Run as Administrator - it will not prompt.
  4. Install Rust 64-bit. Install toolchain nightly-2018-04-04 and set it as default. For the moment, 32-bit builds also require a 32-bit Rust.

You need all of these to be in %PATH%. Edit ci/wintools/SETUP_PATH.bat as appropriate to ensure that rust/cargo, nasm, git, and Git/mingw64/bin are all available.

  1. Run win_enter_env.bat to start a sub-shell with VS tools loaded and a proper PATH. Edit the file per its comments to target a 32-bit build (you may want a separate imageflow folder for each target).
  2. cd ..\.. back to the root and run win_build_c.bat again.
  3. Run win_build_rust.bat to compile the Rust components

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".

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.

Source organization

Rust crates

  • imageflow_types - Shared types, with JSON serialization
  • imageflow_helpers - Common helper functions and utilities
  • imageflow_riapi - RIAPI and ImageResizer4 compatibility parsing/layout
  • imageflow_core - The main library
  • imageflow_abi - The C-Compatible API - exposes functionality from imageflow_core
  • imageflow_tool
  • imageflow_server

C source is located in ./c_components/lib, and ./c_components/tests

Headers for libimageflow.dll are located in bindings/headers

Known flaws and missing features (as of July 2017)

Flaws

  • [ ] imageflow_server doesn't expose the JSON API yet.
  • [ ] No fuzz testing or third-party auditing yet.

Missing features

  • [ ] Animated GIF write support (reading individual frames is supported)
  • [ ] Some advanced rendering features: Whitespace detection/cropping, watermarking, blurring.
  • [ ] Automatic encoder selection and tuning.

Delayed features

  • [ ] Job cost prediction (delayed - no interest from community)
  • [ ] Node bindings (delayed - no interest from community)