Previously, vips combined a block shrink, a variable-sized anti-alias filter, a fixed-size resampler, and a final sharpen. This approach had two main problems: first, you had to have the anti-alias filter tuned very carefully to get nice results and it was hard to find a tuning rule which worked for all images. Secondly, the slowest part of the chain of four operations was the fixed-size resample, and this could not be easily vectorized, since the vector lengths were too small.
The new vips 8.3 shrinker is just two operations: a new block shrinker, and a new variable-sized lanczos3. There's no tuning required, so quality is always great, and the two new operations have been designed to be vectorizable, so performance is up too.
There's a new page on the vips wiki which runs through the new shrinker in some detail, so have a look there if you're curious.
Quality
Here's an interesting test image from Scott Kevill. First, vips 8.1 shrinking the 800x600 original down to 600x450:
It's not too bad, but there is some moiré fringing in the roof tiles and it could be a little sharper. Here's the new code in vips 8.3 doing the same task:
The patterns in the roof tiles have pretty much gone, and it also looks sharper. Put the two images into two tabs and try flipping between them. The original image plus a number of other resizes, including the output of ImageMagick, are on this page.
Performance
The speedup you'll see depends on the image format and the size change. It's most dramatic with TIFF.
Here's vips 8.1 shrinking a 10,000 x 10,000 uncompressed RGB TIFF to a 128x128 pixel JPEG:
$ time vipsthumbnail wtc.tifvips 8.3 is more than twice as fast:
real 0m0.559s
user 0m0.468s
sys 0m0.092s
$ time vipsthumbnail wtc.tifWith JPEG it's less impressive, since almost all the work is done by the JPEG decoder, and that's obviously unchanged.
real 0m0.238s
user 0m0.172s
sys 0m0.064s
mem 50mb
Here's the same image, but as JPEG with vips 8.1:
$ time vipsthumbnail wtc.jpgAnd with 8.3:
real 0m0.294s
user 0m0.284s
sys 0m0.008s
$ time vipsthumbnail wtc.jpgIf you ask for a 2,000 x 2,000 pixel output image it looks better, since vips will actually have some work to do. With 8.1 it was
real 0m0.272s
user 0m0.256s
sys 0m0.016s
mem 24mb
$ time vipsthumbnail wtc.jpg -s 2000And 8.3 is now:
real 0m1.032s
user 0m2.864s
sys 0m0.040s
$ time vipsthumbnail wtc.jpg -s 2000For comparison, here's ImageMagick doing the same tasks:
real 0m0.491s
user 0m0.924s
sys 0m0.048s
mem 69mb
$ time convert wtc.tif -resize 128 tn_wtc.jpgvips is usually faster and occasionally a lot faster.
real 0m2.687s
user 0m4.120s
sys 0m0.512s
mem 705mb
$ time convert -define jpeg:size=256x256 wtc.jpg -resize 128 tn_wtc.jpg
real 0m0.259s
user 0m0.284s
sys 0m0.000s
mem 19mb
$ time convert -define jpeg:size=4000x4000 wtc.jpg -resize 2000 tn_wtc.jpg
real 0m1.165s
user 0m2.476s
sys 0m0.352s
mem 285mb
Hi John,
ReplyDeleteI'm using Vips::Image affine to do fractional rotation and asymmetrical scaling of images from 2K to about a third of that size (frames from movie films). I suppose these new changes to image shrinking do not apply to affine?
Regards, Paul Howson.
Hi Paul, no, no change to affine. You could use shrink to downsize by x2 and then affine from that, but it would probably be slower.
Delete