Skip to content

Commit dbb76c1

Browse files
committed
update readme and changelog
1 parent 3662acb commit dbb76c1

2 files changed

Lines changed: 83 additions & 124 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ This is the changelog for Image version 0.43.0 released on February 27th, 2024.
552552

553553
* `Image.erode/2` and `Image.dilate/2` now take a `radius` parameter rather than a `pixels` parameter. Both functions have been refactored to allow a radius in the range `1..5` with a default of `1`. The radius represents the dimension of the matrix used in the `Vix.Vips.Operations.range/4` function that underpins dilation and erosion. As such they represent the *approximate* number of pixels eroded or dilated. In addition, this function now results in a single `libvips` operation. The previous implementation created `n` operations (where `n` was the value of the `pixels` param) that could result in a slow imaging pipeline and in some cases a [segfault of the entire VM due to stack space exhaustion in libvips](https://github.com/elixir-image/image/issues/125).
554554

555-
* The signature for `Image.linear_gradient/{1..3}` has changed. The function now takes:
555+
* The signature for `Image.linear_gradient/{1..3}` has changed. The function now takes:
556556
* An image and an optional keyword list of options
557557
* A width and height as numbers and a keyword list of options
558558

README.md

Lines changed: 82 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,64 @@
11
# Image
22

3-
`Image` is a fast, memory-efficient image processing library for
4-
Elixir. It is a high-level wrapper around
5-
[Vix](https://hex.pm/packages/vix), the Elixir bindings for the
6-
[libvips](https://www.libvips.org) C library, and provides an
7-
idiomatic functional API for image manipulation, drawing, text
8-
rendering, EXIF/XMP metadata, video frame extraction (via
9-
Xav/FFmpeg), QR code encoding and decoding (via eVision),
10-
blurhash, perceptual hashing, and many other image-related
11-
operations.
12-
13-
Machine-learning features (object detection, image
14-
classification, image generation) live in the companion
15-
[`image_detection`](https://hex.pm/packages/image_detection)
16-
library, which depends on `:image` and pulls in
17-
[Bumblebee](https://hex.pm/packages/bumblebee) and
18-
[Nx](https://hex.pm/packages/nx) as its own optional
19-
dependencies.
20-
21-
In a simple resize benchmark, `Image` is approximately 2 to 3 times
22-
faster than [Mogrify](https://hex.pm/packages/mogrify) and uses
23-
about 5 times less memory.
3+
`Image` is a fast, memory-efficient image processing library for Elixir. It is a high-level wrapper around [Vix](https://hex.pm/packages/vix), the Elixir bindings for the [libvips](https://www.libvips.org) C library, and provides an idiomatic functional API for image manipulation, drawing, text rendering, EXIF/XMP metadata, video frame extraction (via Xav/FFmpeg), QR code encoding and decoding (via eVision), blurhash, perceptual hashing, and many other image-related operations.
4+
5+
Machine-learning features (object detection, image classification, image generation) live in the companion [`image_detection`](https://hex.pm/packages/image_detection) library, which depends on `:image` and pulls in [Bumblebee](https://hex.pm/packages/bumblebee) and [Nx](https://hex.pm/packages/nx) as its own optional dependencies.
6+
7+
In a simple resize benchmark, `Image` is approximately 2 to 3 times faster than [Mogrify](https://hex.pm/packages/mogrify) and uses about 5 times less memory.
248

259
Documentation can be found at <https://hexdocs.pm/image>.
2610

2711
## Features
2812

29-
* **Image processing** — open, write, resize, thumbnail, crop, embed,
30-
rotate, flip, flatten, trim, replace colour, chroma key, warp
31-
perspective, distort, blur (Gaussian, box, bilateral), sharpen,
32-
modulate, vibrance, tone map, local contrast, equalize, blend,
33-
composite, mask, dilate / erode, edge detect.
34-
35-
* **Drawing**`Image.Draw` provides points, rectangles, circles,
36-
lines, masks, flood fill, image overlay, smudge.
37-
38-
* **Text rendering**`Image.Text` produces antialiased text overlays
39-
with full Pango markup support, font selection, alignment,
40-
background fills, stroke, and per-character control.
41-
42-
* **Colour management** — colour arguments accept atoms, hex strings,
43-
CSS named colours, hex shorthand, `#RRGGBBAA`, `Color.*` structs,
44-
CSS Color 4 / 5 functions (`rgb()`, `hsl()`, `lab()`, `oklch()`,
45-
`color-mix()`, relative colour syntax via `from`, `none` keyword,
46-
`calc()`), and are converted to the **target image's interpretation**
47-
via `Image.Pixel.to_pixel/3`. The same colour string draws correctly
48-
on sRGB, Lab, scRGB, CMYK, 16-bit, and greyscale images.
49-
50-
* **Colour spaces**`Image.colorspace/1`, `Image.to_colorspace/2`,
51-
and full conversion between sRGB / scRGB / Lab / LCh / CMYK / HSV /
52-
XYZ / B&W / 16-bit RGB.
53-
54-
* **Dominant colour and palette extraction**`Image.dominant_color/2`
55-
with two methods: a fast 3D-histogram (default) and an
56-
imagequant-backed perceptual quantiser. See
57-
[`guides/performance.md`](guides/performance.md) for benchmarks.
58-
59-
* **K-means clustering**`Image.k_means/2` (when `:scholar` is
60-
available) returns the dominant colour palette extracted by
61-
unsupervised clustering.
62-
63-
* **Histogram operations**`Image.histogram/1`, `Image.equalize/2`,
64-
per-band statistics, percentile, mean, median.
65-
66-
* **Metadata**`Image.exif/1` for EXIF, `Image.Xmp.extract_xmp/1` for
67-
XMP, plus `Image.minimize_metadata/1` to strip metadata while
68-
retaining the artist and copyright fields.
69-
70-
* **ICC colour profiles**`Image.ICCProfile` for libvips' built-in
71-
profiles (`:srgb`, `:cmyk`, `:p3`) and arbitrary `.icc` files.
72-
73-
* **Image streaming** — open and write directly from `File.Stream`s,
74-
Plug `Conn`s, in-memory binaries, and S3 sources.
75-
76-
* **Optional ML integrations**
77-
* `Image.Video` (frame extraction, seek, webcam) via
78-
[Xav](https://hex.pm/packages/xav), an Elixir wrapper around
79-
FFmpeg. Requires FFmpeg ≥ 6.0 on the system.
80-
* `Image.QRcode` (encode + decode) via
81-
[eVision](https://hex.pm/packages/evision).
13+
* **Image processing** — open, write, resize, thumbnail, crop, embed, rotate, flip, flatten, trim, replace colour, chroma key, warp perspective, distort, blur (Gaussian, box, bilateral), sharpen, modulate, vibrance, tone map, local contrast, equalize, blend, composite, mask, dilate / erode, edge detect.
14+
15+
* **Drawing**`Image.Draw` provides points, rectangles, circles, lines, masks, flood fill, image overlay, smudge.
16+
17+
* **Text rendering**`Image.Text` produces antialiased text overlays with full Pango markup support, font selection, alignment, background fills, stroke, and per-character control.
18+
19+
* **Colour management** — colour arguments accept atoms, hex strings, CSS named colours, hex shorthand, `#RRGGBBAA`, `Color.*` structs, CSS Color 4 / 5 functions (`rgb()`, `hsl()`, `lab()`, `oklch()`, `color-mix()`, relative colour syntax via `from`, `none` keyword, `calc()`), and are converted to the **target image's interpretation** via `Image.Pixel.to_pixel/3`. The same colour string draws correctly on sRGB, Lab, scRGB, CMYK, 16-bit, and greyscale images.
20+
21+
* **Colour spaces**`Image.colorspace/1`, `Image.to_colorspace/2`, and full conversion between sRGB / scRGB / Lab / LCh / CMYK / HSV / XYZ / B&W / 16-bit RGB.
22+
23+
* **Dominant colour and palette extraction**`Image.dominant_color/2` with two methods: a fast 3D-histogram (default) and an imagequant-backed perceptual quantiser. See [`guides/performance.md`](guides/performance.md) for benchmarks.
24+
25+
* **K-means clustering**`Image.k_means/2` (when `:scholar` is available) returns the dominant colour palette extracted by unsupervised clustering.
26+
27+
* **Histogram operations**`Image.histogram/1`, `Image.equalize/2`, per-band statistics, percentile, mean, median.
28+
29+
* **Metadata**`Image.exif/1` for EXIF, `Image.Xmp.extract_xmp/1` for XMP, plus `Image.minimize_metadata/1` to strip metadata while retaining the artist and copyright fields.
30+
31+
* **ICC colour profiles**`Image.ICCProfile` for libvips' built-in profiles (`:srgb`, `:cmyk`, `:p3`) and arbitrary `.icc` files.
32+
33+
* **Image streaming** — open and write directly from `File.Stream`s, Plug `Conn`s, in-memory binaries, and S3 sources.
34+
35+
* **Optional ML integrations** — each is compiled only when its optional dependency is present:
36+
37+
* `Image.Video` (frame extraction, seek, webcam) via [Xav](https://hex.pm/packages/xav), an Elixir wrapper around FFmpeg. Requires FFmpeg ≥ 6.0 on the system.
38+
39+
* `Image.QRcode` (encode + decode) via [eVision](https://hex.pm/packages/evision).
40+
8241
* `Image.k_means` via [Scholar](https://hex.pm/packages/scholar).
42+
8343
* `Image.to_nx/2` / `Image.from_nx/1` via [Nx](https://hex.pm/packages/nx).
84-
* **Object detection, image classification, and image
85-
generation** live in the separate
86-
[`:image_detection`](https://hex.pm/packages/image_detection)
87-
package. Add it alongside `:image` in your `mix.exs` to get
88-
`Image.Detection`, `Image.Classification`, and
89-
`Image.Generation` (which depend on `:axon_onnx` and
90-
[Bumblebee](https://hex.pm/packages/bumblebee) respectively).
9144

92-
* **Hashing** — perceptual difference hash (`Image.dhash/2`),
93-
blurhash encode/decode (`Image.Blurhash`), Hamming distance.
45+
* **Object detection, image classification, and image generation** live in the separate [`:image_detection`](https://hex.pm/packages/image_detection) package. Add it alongside `:image` in your `mix.exs` to get `Image.Detection`, `Image.Classification`, and `Image.Generation` (which depend on `:axon_onnx` and [Bumblebee](https://hex.pm/packages/bumblebee) respectively).
46+
47+
* **Hashing** — perceptual difference hash (`Image.dhash/2`), blurhash encode/decode (`Image.Blurhash`), Hamming distance.
9448

95-
* **YUV interop**`Image.YUV` for raw YUV file/binary I/O in
96-
C420/C422/C444 chroma subsampling and BT.601/BT.709 colour spaces.
49+
* **YUV interop**`Image.YUV` for raw YUV file/binary I/O in C420/C422/C444 chroma subsampling and BT.601/BT.709 colour spaces.
9750

98-
* **Kino integration**`Image.Kino` renders images in
99-
[Livebook](https://livebook.dev) without manual conversion.
51+
* **Kino integration**`Image.Kino` renders images in [Livebook](https://livebook.dev) without manual conversion.
10052

101-
* **Social media presets**`Image.Social` with the standard image
102-
sizes for Twitter, Facebook, Instagram, LinkedIn, Pinterest, YouTube,
103-
Snapchat, and TikTok.
53+
* **Social media presets**`Image.Social` with the standard image sizes for Twitter, Facebook, Instagram, LinkedIn, Pinterest, YouTube, Snapchat, and TikTok.
10454

105-
* **Bundled fonts** — ships the Impact font for meme rendering so
106-
`Image.meme/3` works out of the box.
55+
* **Bundled fonts** — ships the Impact font for meme rendering so `Image.meme/3` works out of the box.
10756

108-
* **Structured errors** — every fallible function returns
109-
`{:ok, value}` or `{:error, %Image.Error{}}`. The error struct
110-
carries `:reason` (atom or `{atom, value}`), `:operation`, `:path`,
111-
`:value`, and a derived `:message`. Bang variants raise the same
112-
struct.
57+
* **Structured errors** — every fallible function returns `{:ok, value}` or `{:error, %Image.Error{}}`. The error struct carries `:reason` (atom or `{atom, value}`), `:operation`, `:path`, `:value`, and a derived `:message`. Bang variants raise the same struct.
11358

11459
## Supported Elixir and OTP releases
11560

116-
`Image` is tested on the following matrix:
61+
`Image` is tested and supported on the following matrix:
11762

11863
| Elixir | OTP |
11964
|---|---|
@@ -122,11 +67,6 @@ Documentation can be found at <https://hexdocs.pm/image>.
12267
| 1.19 | 26, 27, 28 |
12368
| 1.20-rc | 27, 28 |
12469

125-
The minimum supported version is **Elixir 1.17 / OTP 26**. The CI
126-
matrix runs `mix format --check-formatted`, `mix compile
127-
--warnings-as-errors`, the full test suite, and `mix dialyzer` (lint
128-
cell only) on every cell.
129-
13070
## Quick start
13171

13272
Add `:image` to your dependencies:
@@ -263,6 +203,36 @@ Then set `VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPS` at compile
263203
time and at runtime. See the [Vix documentation](https://hexdocs.pm/vix)
264204
for the full list.
265205

206+
## Installing FFmpeg (for `Image.Video`)
207+
208+
`Image.Video` is powered by [Xav](https://hex.pm/packages/xav), which wraps the FFmpeg C libraries as a NIF. FFmpeg itself is not bundled — you need to install the FFmpeg development packages (version 4.x – 7.x) on the system where `:image` is compiled *and* where it runs.
209+
210+
`Image.Video` and the `:xav` optional dependency only compile when these libraries are present. Projects that don't use video don't need to install anything here.
211+
212+
```bash
213+
# macOS (Apple Silicon)
214+
brew install pkg-config ffmpeg
215+
216+
# macOS (Intel)
217+
brew install ffmpeg
218+
219+
# Debian / Ubuntu
220+
apt install libavcodec-dev libavformat-dev libavutil-dev \
221+
libswscale-dev libavdevice-dev
222+
223+
# Fedora / RHEL
224+
dnf install pkg-config ffmpeg-devel ffmpeg-libs
225+
```
226+
227+
Note: Fedora's default repositories don't ship FFmpeg. Enable
228+
[RPM Fusion](https://rpmfusion.org/) first with
229+
`dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm`
230+
before installing `ffmpeg-devel`.
231+
232+
Windows is not currently supported by Xav. See the
233+
[Xav installation guide](https://github.com/elixir-webrtc/xav/blob/main/INSTALL.md)
234+
for the upstream source of these commands and any updates.
235+
266236
## Optional dependencies
267237

268238
`Image` is small and self-contained at its core. The following
@@ -288,13 +258,12 @@ is conditionally compiled. Add only the deps you actually use.
288258
debugging, concurrency, memory leak detection, and security. Each
289259
has a sensible default; the most commonly tuned ones:
290260

291-
* `VIPS_BLOCK_UNTRUSTED=TRUE` (set automatically when the `:image`
292-
application starts) prevents libvips from loading untrusted format
293-
loaders.
294-
* `VIPS_CONCURRENCY=N` caps the libvips thread pool. Default is
295-
the system core count. Lower it if image processing is competing
296-
with other workloads.
261+
* `VIPS_BLOCK_UNTRUSTED=TRUE` (set automatically when the `:image` application starts) prevents libvips from loading untrusted format loaders.
262+
263+
* `VIPS_CONCURRENCY=N` caps the libvips thread pool. Default is the system core count. Lower it if image processing is competing with other workloads.
264+
297265
* `VIPS_LEAK=true` enables libvips' memory leak reporter.
266+
298267
* `G_DEBUG=fatal-criticals` aborts on the first GLib critical.
299268

300269
You can also set the concurrency programmatically with
@@ -334,23 +303,13 @@ suppressing stderr will also hide real FFmpeg errors.
334303

335304
## Security considerations
336305

337-
* `libvips` and the underlying loaders are written in C; a malicious
338-
input has the potential to crash the BEAM if libvips itself crashes.
339-
In comparison to ImageMagick (638+ CVEs across its history),
340-
libvips has had a much smaller attack surface (~8 CVEs, all
341-
promptly fixed).
306+
* `libvips` and the underlying loaders are written in C; a malicious input has the potential to crash the BEAM if libvips itself crashes. In comparison to ImageMagick (638+ CVEs across its history), libvips has had a much smaller attack surface (~8 CVEs, all promptly fixed).
342307

343-
* The `:image` application sets `VIPS_BLOCK_UNTRUSTED=TRUE` on start
344-
unless the user has set it explicitly. This blocks libvips from
345-
loading the more dangerous format loaders.
308+
* The `:image` application sets `VIPS_BLOCK_UNTRUSTED=TRUE` on start unless the user has set it explicitly. This blocks libvips from loading the more dangerous format loaders.
346309

347-
* When displaying user-supplied images on a web page, sanitise
348-
EXIF / XMP metadata before passing it to a browser — embedded
349-
HTML in metadata fields is a known vector.
310+
* When displaying user-supplied images on a web page, sanitise EXIF / XMP metadata before passing it to a browser — embedded HTML in metadata fields is a known vector.
350311

351-
* Image processing is CPU-intensive and the default libvips
352-
concurrency equals the host core count. For multi-tenant
353-
workloads, lower `VIPS_CONCURRENCY` to avoid CPU starvation.
312+
* Image processing is CPU-intensive and the default libvips concurrency equals the host core count. For multi-tenant workloads, lower `VIPS_CONCURRENCY` to avoid CPU starvation.
354313

355314
## License
356315

0 commit comments

Comments
 (0)