Here’s a summary of what’s new in libvips 8.16. Check the ChangeLog if you need more details.
Signed Distance Fields
libvips has a new
vips_sdf()
operator. This can efficiently generate a range of basic shapes as Signed
Distance Fields – these are images where each pixel contains a signed value
giving the distance to the closest edge. For example:
$ vips sdf x.v 512 512 circle --r=200 --a="256 256"
Makes a 512 x 512 pixel float image of a circle with radius 200, centered on 256 x 256. As you move out and away from the edge, values become increasingly positive, as you move within the circle, values become negative.

The great thing about SDFs is that they are quick to make and very easy to combine to make more complex shapes. For example, you could write:
#!/usr/bin/env python3
import sys
import pyvips
box = pyvips.Image.sdf(1000, 1000, "rounded-box",
a=[300, 400],
b=[700, 600],
corners=[100, 0, 0, 0])
circle = pyvips.Image.sdf(1000, 1000, "circle",
a=[500, 300],
r=100)
line = pyvips.Image.sdf(1000, 1000, "line",
a=[500, 500],
b=[600, 900])
# union
sdf = box.minpair(circle).minpair(line)
# make annular
sdf = sdf.abs() - 15
# render as an antialiased image
sdf.clamp().linear(-255, 255, uchar=True).write_to_file(sys.argv[1])
To make:

Hmmm, possibly a person rowing a boat. This uses three
other new operators: vips_minpair() and vips_maxpair(),
which given a pair of images find the
pixel-wise max and min, and vips_clamp(), which constrains pixels
to a range.
SDFs fit really well with libvips on-demand-evaluation. These things never really exist, they are just chains of delayed computation, so you can make them any size, and compute them in parallel.
Up until now we’ve used SVG rendering to generate masks for large images. SDFs are a lot faster and need much less memory – as long as you only need simple shapes, they should be a great replacement.
Better file format support
File format support has been improved (again). Highlights this time are:
-
JXL load and save now supports exif, xmp, and animation.
-
webpsavenow hastarget_sizeparameter to set desired size in bytes and apassesparameter to set number of passes to achieve desired target size, plus asmart_deblockoption for better edge rendering. -
tiffloadsupports old-style JPEG compression. -
tiffsavenow lets you change the deflate compression level. -
All paletteised images now have a
palettemetadata item. -
PFM load and save now uses scRGB colourspace (ie. linear 0-1).
-
rawsavegets streaming support withvips_rawsave_target()andvips_rawsave_buffer().
General improvements
There have been some smaller libvips additions and improvements too.
-
libvips used to limit image dimensions to 10 million pixels. This is now configurable, see
vips_max_coord_get(). -
There’s a new (trivial)
vips_addalpha()operation. -
vips_getpoint()has a newunpack_complexoption. -
vipsheadersupports multiple-f fieldarguments. -
libvips now includes basic
g_autosupport, making C programming slightly more convenient.
Plus some even more minor bugfixes and improvements.