This page has been reworked into a chapter in the official libvips documentation.
https://libvips.github.io/libvips/API/current/Making-image-pyramids.md.html
Please see that page rather than this one.
If you have any questions, please ask on the libvips issue tracker:
https://github.com/libvips/libvips/issues
Here's the original text of this page, for reference:
A new version of libvips has just been released and it includes an updated version of the pyramid builder. I thought I'd write a short introduction and show some benchmarks.
Here's the Zoomify viewer working on a large image. These things are very easy to make: you convert your source image into a pyramid of tiles, then copy them to your webserver together with a scrap of javascript.
Building the image pyramid can be slow. For example, Zoomify Image is a popular Zoomify pyramid builder and
wtc.tif
is a 10,000 by 10,000 pixel RGB image:vips is almost 10 times faster:$ time python ZoomifyFileProcessor.py ~/pics/wtc.tif real 0m22.520s user 0m17.035s sys 0m5.419s Peak mem 400MB
vips can load images using the openslide library. This means you can make pyramids of medical images very quickly. For example, openslide includes a DeepZoom tiler written in Python, and$ time vips dzsave wtc.tif x --layout zoomify real 0m2.581s user 0m7.675s sys 0m3.534s Peak mem 120MB
54479.svs
is a 45,000 by 45,000 pixel slide compressed with a jpeg2000 codec:vips is around 7 times faster:$ time python deepzoom_tile.py ~/pics/jp2k/54479.svs Tiling slide: wrote 36663/36663 tiles real 56m4.753s user 100m22.116s sys 3m1.863s
Though this is more than a little unfair, the openslide DeepZoom writer is not primarily designed for batch use.$ time vips dzsave 54479.svs x real 7m56.462s user 9m9.018s sys 0m42.475s
vips memory use scales with image width, not number of pixels, so it can process very large images without using much memory. I've made pyramids of 150,000 by 150,000 pixel images with no problems, and it should go quite a bit larger than that.
Run dzsave with no arguments to see a summary:
There are also the API docs.$ vips dzsave save image to deep zoom format usage: dzsave in filename where: in - Image to save, input VipsImage filename - Filename to save to, input gchararray optional arguments: layout - Directory layout, input VipsForeignDzLayout default: dz allowed: dz, zoomify, google suffix - Filename suffix for tiles, input gchararray overlap - Tile overlap in pixels, input gint default: 1 min: 0, max: 8192 tile-size - Tile size in pixels, input gint default: 254 min: 1, max: 8192 centre - Center image in tile, input gboolean default: false depth - Pyramid depth, input VipsForeignDzDepth default: onepixel allowed: onepixel, onetile, one angle - Rotate image during save, input VipsAngle default: d0 allowed: d0, d90, d180, d270 container - Pyramid container type, input VipsForeignDzContainer default: fs allowed: fs, zip properties - Write a properties file to the output directory, input gboolean default: false compression - ZIP deflate compression level, input gint default: 0 min: -1, max: 9 strip - Strip all metadata from image, input gboolean default: false background - Background value, input VipsArrayDouble
Writing DeepZoom pyramids
The--layout
option sets the basic mode of operation. With no --layout
, dzsave writes DeepZoom pyramids. For example:This will create a directory called$ vips dzsave huge.tif mydz
mydz_files
containing the image tiles, and write a file called mydz.dzi
containing the image metadata. You can use the
--suffix
option to control how tiles are written. For example:will write JPEG tiles with the quality factor set to 90. You can set any format write options you like, see the API docs for vips_jpegsave() for details.$ vips dzsave huge.tif mydz --suffix .jpg[Q=90]
Writing Zoomify pyramids
Use--layout zoomify
to put dzsave into zoomify mode. For example:This will create a directory called$ vips dzsave huge.tif myzoom --layout zoomify
myzoom
containing a file called ImageProperties.xml
with the image metadata in, and a series of directories called TileGroupn
, each containing 256 image tiles. As with DeepZoom, you can use
--suffix
to set jpeg quality. Writing Google Maps pyramids
Use--layout google
to write Google maps-style pyramids. These are compatible with the NYU Pathology pyramid builder. For example:Will create a directory called$ vips dzsave wtc.tif gmapdir --layout google
gmapdir
containing blank.png
, the file to display for blank tiles, and a set of numbered directories, one for each zoom level. The pyramid can be sparse (blank tiles are not written).As with DeepZoom, you can use
--suffix
to set jpeg quality. Use
--background
to set the background colour. This is the colour displayed for bits of the pyramid not in the image (image edges, for example). By default, the image background is white.Use
--centre
to add a border to the image large enough to centre the image within the lowest resolution tile. By default, images are not centred.For example:
$ vips dzsave wtc.tif gmapdir --layout google --background 0 --centre
Other options
You can use--tile-size
and --overlap
to control how large the tiles are and how they overlap (obviously). They default to the correct values for the selected layout.You can use
--depth
to control how deep the pyramid should be. Possible values are onepixel
, onetile
and one
. onepixel
means the image is shrunk until it fits within a single pixel. onetile
means shrink until it fits with a tile. one
means only write one pyramid layer (the highest resolution one). It defaults to the correct value for the selected layout. --depth one
is handy for slicing up a large image into tiles (rather than a pyramid). You can use
--angle
to do a 90, 180 or 270 degree rotate of an image during pyramid write.With 7.40 and later, you can use
--container
to set the container type. Normally dzsave will write a tree of directories, but with --container zip
you'll get a zip file instead. Use .zip as the directory suffix to turn on zip format automatically:to write a zipfile containing the tiles.$ vips dzsave wtc.tif mypyr.zip
Preprocessing images
libvips 7.36 and later let you use .dz as a filename suffix, meaning send the image to dzsave. This means you can write the output of any vips operation to a pyramid. For example:The arguments to$ vips extract_area huge.svs mypy.dz[layout=google] 100 100 10000 10000
extract_area
are image-in, image-out, left, top, width, height. So this command will cut out a 10,000 by 10,000 pixel area from near the top-left-hand corner of an Aperio slide image, then build a pyramid in Google layout using just those pixels.If you are working from OpenSlide images, you can use the shrink-on-load feature of many of those formats. For example:
Will pull out level 1 (the half-resolution level of an MRXS slide) and make a pyramid from that.$ vips dzsave CMU-1.mrxs[level=1] x
Troubleshooting
If you are building vips from source you do need to check the summary at the end of configure carefully. You must have thelibgsf-1-dev
package for dzsave to work.
I didn't see anything in the API but are there any settings I have to use to make jpeg2000 work? I am having trouble tiling this test file http://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1-JP2K-33005.svs
ReplyDeleteHi, it should just work. Have you built libvips yourself? Perhaps you're missing openslide? Open an issue on the vips issue tracker on github:
ReplyDeletehttps://github.com/jcupitt/libvips/issues
I tried your image on this (very slow) machine and it works OK for me:
ReplyDelete$ time vips dzsave CMU-1-JP2K-33005.svs x
real 9m58.659s
user 12m29.699s
sys 0m51.943s
$
If you built libvips from source, check the configure output and make sure everything looks OK. Make sure it's found your openslide. Also check for openjpeg, the jp2k decoder library.
Thanks for this post, its really helpful for processing Aperio files.
ReplyDeleteOne question though, is there any easy way to import a slide thats split across many .TIFF files from the command line? Right now I'm using a script that does it using the MS Image Compositing Editor but its slow and memory inefficient because it loads the entire file into memory at once.
You can use "vips insert" to paste two images together:
ReplyDeletehttp://www.vips.ecs.soton.ac.uk/supported/7.32/doc/html/libvips/libvips-conversion.html#vips-insert
At the command-line, it's something like:
vips insert big.tif small.tif out.tif 200 100 --expand --background 255
will make out.tif, a copy of big.tif with small.tif pasted in at 200, 100, expanded if necessary, and with new background pixels set to 255.
There are other operators which will do a feathered join or search for features to find the overlap distance. You can use the GUI too.
I see, thanks. One other question, does doing a join like this require loading the entire image into RAM at once or is it possible to stream it from disk while tiling?
ReplyDeleteYes, "vips insert" will stream the image.
ReplyDeletethe output of the --layout google is a directory structure based on zoom levels with numbered jpegs in folders and a blank.png in the home folder, however, on the NYUVM site they say their slide tiling script for use with their virtual microscope produces tiles with a naming convention "tile_z_x_y.jpg". i was never able to get their slide tiling script to work with my aperio slides but wondered if this vips google output would still be compatible with their viewer?
ReplyDeleteI'm told it works with at least one of the GM viewers. There seem to be several viewers all with slightly different tile naming conventions. You might need to write a tiny script to rename the tiles.
DeleteLooking at the viewer example here:
Deletehttp://code.google.com/p/virtualmicroscope/wiki/simpleviewerexample
You just need to change the customGetTileUrl() function.
Change it to be something like:
return "http://mysite.com/images/slide14/" + zoom + "/" + coord.y + "/" + coord.x + ".jpg"
Does it have any adapter that alows to store result tiles in S3 buckets?
DeleteAs it is, dzsave will only write to a filesystem.
DeleteYou'd need to add some sort of swappable backend I guess. It shouldn't be too hard, sources here if you're curious:
https://github.com/jcupitt/libvips/blob/master/libvips/foreign/dzsave.c
strip_work() calls vips_image_write_to_file() to save each tile. You'd just need to change that to call vips_jpegsave_buffer() instead (write an image to memory in jpeg format) then send that buffer to S3. There are a couple of other bits of dzsave you'd need to adapt as well, but nothing difficult.
vips-7.40 and later use libgsf to write the tiles. This lets you send the output to any structured storage, for example to a zip file:
Deletevips dzsave huge.tif mypyr.zip
will writes the whole pyramid directly to a zip file.
Hi all,
ReplyDeleteI try to use vips and the dzsave option (on Ubuntu LT12.04). I successfully installed vips and modules (I think). Here my .configure output:
* general build options
native win32: no
native OS X: no
open files in binary mode: no
enable debug: no
build C++ components: yes
build docs with gtkdoc: no
install docs: yes
gobject introspection: no
* optional packages and modules
use fftw3 for FFT: yes
Magick package: MagickWand
file import with libMagick: yes
accelerate loops with orc: yes
(requires orc-0.4.11 or later)
ICC profile support with lcms: yes (lcms2)
file import with OpenEXR: yes
file import with OpenSlide: yes
(requires openslide-3.3.0 or later)
file import with matio: yes
file import with cfitsio: yes
file import/export with libwebp: no
text rendering with pangoft2: yes
file import/export with libpng: yes (pkg-config libpng >= 1.2.9)
(requires libpng-1.2.9 or later)
file import/export with libtiff: yes (found by search)
file import/export with libjpeg: yes
image pyramid export: yes
(requires libgsf-1 1.14.27 or later)
use libexif to load/save JPEG metadata: yes
build Python binding: yes
Unfornutately, I don't have the dzsave option. Could you help me?
Your configure output looks OK. Perhaps it's a problem with paths or building? Please open an issue on the vips bugtracker and I'll help fix it:
Deletehttps://github.com/jcupitt/libvips/issues
FYI, I found a post to add more librairies as follow:
Deleteapt-get install -qq automake gobject-introspection gtk-doc-tools libfftw3-dev libglib2.0-dev libjpeg-turbo8-dev libpng12-dev libwebp-dev libtiff4-dev libxml2-dev swig libmagick++-dev bc libgsf-1-dev libcfitsio3-dev libgsl0-dev libmatio-dev
Now, I'm able to use vips dzsave perfectly. Probably a missing library...
Is it possible to use vips to generate tiles with transparent background and png format? If so can someone point me to an example? Thanx
ReplyDeleteYes, you just need to pick png as your output image format. Example:
Delete$ vips dzsave lion.png x --suffix .png
$ ls x_files/10/
0_0.png 0_2.png 1_0.png 1_2.png 2_0.png 2_2.png
0_1.png 0_3.png 1_1.png 1_3.png 2_1.png 2_3.png
Beware that png is very slow and needs a lot of disk space.
I'm trying to scan slides (similar to the NYU virtual slides) for use in Google Maps. I have everything working, but I'm wondering if, since the Google Maps tiles can be sparse, is there a way I can systematically delete all of the extra white tiles that you usually see in a slide (example here: http://education.med.nyu.edu/virtualmicroscope/v/1540/)? It could really reduce total file size to just have the smaller white tiles removed and the blank.png image replacing them as needed, but it would be challenging to manually remove every white or close-to-white image in those folders.
ReplyDeleteAlso, thank you so much for doing this. Vips is a phenomenal tool.
There was an issue about this on the vips tracker:
Deletehttps://github.com/jcupitt/libvips/issues/352
With some code to automatically remove background tiles, but it was never merged because we were unable to test it. If you post on that issue, we could try again.
(and thanks for your kind words about vips)
DeleteI'll give it a shot! I'll check out that link.
DeleteThis feature was added late last year, so pyramids are all sparse now.
DeleteHi,
ReplyDeleteI want to generate deep zoom tiles for an image of size 55,000 x 55,000 pixels. I tried using deep zoom software's but they keep loading the file without any success. Now i have downloaded vips on windows and from the command line I am trying to generate deep zoom tiles. The command i am using is
vips dzsave huge.tif mydz --suffix .png
but it is not giving me good quality. I have currently tried small files to firts test the result. I have couple of questions. First, would it work on such large file? secondly, how to improve the quality?
Thanks
Hi, yes, I regularly make 200,000 x 200,000 pyramids on my small laptop, it should be fine. What do you mean by bad quality? What fault are you seeing?
ReplyDeleteI would open an issue on the libvips tracker. You can post sample images and it's a much better way to debug issues.
https://github.com/jcupitt/libvips/issues
Thanks John. I used vips and it worked as a charm. I still have a question about quality. For the same image, if i generate deep zoom tiles through deep zoom composer i am getting images in the tiles with bit depth of 32 bits. However for the same image vips is generating tile images with bit depth of 24 bits. So colors look bit bad as compare to deep zoom composer tiles images. Why is it so? How can i generate deep zoom tiles with better bit rate? Thanks
ReplyDeleteThe 24/32 thing is the alpha channel: Deep Zoom Composer is adding an extra alpha channel you don't need. If colours don't look the same, it's probably because of an ICC profile. Make an issue on libvips github and we can track down the problem.
ReplyDeleteI want know how to convert a BMP image to JP2. faster than kakadu on windows OS.
ReplyDeleteI need to create multilevel zoom image (pyramid).
Kakadu creates jp2 with factor of 2. is it possible to create more immediate layers?
Hi, vips doesn't really support jp2. There are no good, free libraries for the format and it's very little used.
ReplyDeleteHi John,
ReplyDeleteis there any way to tile a PDF?
and if yes how much time does VIPS takes to tile 25mb pdf?
Thanks
Manjinder
Hello, sure, should be fine. It uses poppler to render PDFs, so it ought to be quick, but it does depend a bit on what's in the document. On this laptop, I see:
ReplyDelete$ time vips dzsave nipguide.pdf[page=10,dpi=1200] x
real 0m9.640s
user 0m16.528s
sys 0m2.440s
That's rendering a page from the nip2 manual containing a mixture of text and graphics at 1200 DPI to make a 9,000 x 15,000 pixel image and saving as a pyramid.
Hello John,
ReplyDeleteI am trying to config vips on my PC. that is windows PC. I want to use VIPS on command prompt of window. For this I download ni2-x.x.x from download link you provided. And also try some other settings and follow other links, but I am not able to run vips commands. Please help me in configurations of VIPS on windows 7 and upper system.
Example I want to run same command you mentioned above.
"time vips dzsave nipguide.pdf[page=10,dpi=1200] "
How can I get this on windows?
Thanks,
Manjinder Singh
Hi, download vips-dev-w64-all-8.5.4.zip (the current latest version) from here:
ReplyDeletehttps://github.com/jcupitt/libvips/releases
unzip somewhere, then cd to the vips-8.5.4/bin folder, and enter
vips.exe dzsave huge.tif x
or whatever. If you want to be able to run vips.exe from anywhere on your system, you will need to set your PATH.
Hi Mr. Cuppit, I'm working on a virtual microscope and I got the .svs files, but when I use the dzsave with google layout some images are left with 7 layers and others with 9, why is that?, Also is there any way I can get just 7 layers always?.
ReplyDeletein advance thanks for your help, And thanks a lot for taking the time to develop this library it's really awesome and usefull
It depends on the size of the slide and the magnification you use. If you use one of the standard viewers, like openseadragon, it shouldn't matter, the viewer will just pull down the bits it needs.
DeleteI suppose you could resize to a standard size before converting with dzsave.
I'm using the google maps API, does the amount of layer depend on the image resolution?
DeleteYes. Each layer is half the size of the layer below, so the number of layers depends on how large the original image is. For example, if you have a 1024 x 1024 pixel original, the layers will be:
Delete1024 x 1024
512 x 512
256 x 256
128 x 128
So four layers. If you have a 8192 x 8192 original, you'll have seven layers.
Hi Mr. Cuppit, I'm working on a virtual microscope and I got the .svs files, but when I use the dzsave with google layout some images are left with 7 layers and others with 9, why is that?, Also is there any way I can get just 7 layers always?.
ReplyDeletein advance thanks for your help, And thanks a lot for taking the time to develop this library it's really awesome and usefull
Just to say: I discover your tool while working on a webgame powered by leaflet. It's great. Fast, and light, perfect !
ReplyDeleteI haven't managed to define properly the zoom level. I did :
vips dzsave HUGE_PIC.png mapTiles --layout google --suffix .png --depth onetile
And I get, from a 32768x32768 px picture, zoomlevels from 0 to 7. I would like to have from 0 to 10 (or whatever) - how can I reach that ?
(For now, I use the resize tools to create gigantic pictures, and then I can have more zoom levels).
Hi,
ReplyDeleteFirst of all, thank you for your tool ! It save me a lot of time and is powerfull and ligth.
I'm looking for a way to change the number of zoomlevel to genereate with dzsave.
I did :
vips dzsave PIC.png mapFolder --layout google --suffix .png --depth onetile
And it create from a 32768x32768 px picture a tileset allowing zoom from 0 to 7...
I notice that if I work with bigger or smaller picture, it did different level of zoom according to this.
I make a game, and I need 0 to 10 levels of zoom - for now, I'm resize the original pic bigger and bigger, but is there an option to juste change the level of zoom to generate from a specific piture ?
Thank again for your work.
Hello, it always shrinks the image by x2, and stops when the image fits in one tile. This means the number of layers is ((log2(image size) - log2(tile size)).
ReplyDeleteYou can size the image up in libvips, for example:
vips resize PIC.png mapFolder.dz[layout=google,suffix=.png,depth=onetile] 8
and it'll make the image 8x larger before building the pyramid. If the image is 8x larger, it will need log2(8), or three more layers.
Hi John,
ReplyDeleteFirst of all, thank you for very much writing this amazing tool and still supporting it after all these years!
I have a strange behaviour that I wanted to consult you about:
While trying to convert an mrxs file with 22 levels (0-21), the result stops after 12 levels (0-11).
Here's the command I'm using
vips dzsave 1.mrxs dz1
Am I missing something?
Thanks
It should work. Open an issue on the libvips tracker and I'll help debug your problem:
Deletehttps://github.com/jcupitt/libvips/issues
Hi John -
ReplyDeleteMirroring everyone else's comments - thanks for this work. I have used vips for years now.
I have a new scanner to create tiff formats, when I try and run them through vips using:
vips dzsave 84045T_001.tif dzs/84045001 --background 0 --centre --layout google
I am getting errors I've never seen:
(vips:7861): VIPS-WARNING **: 09:24:01.682: error in tile 1792 x 0
TIFFFillTile: 0: Invalid tile byte count, tile 7
(repeating errors for subsequent 7 tiles (7-14)) ...
Can you point me in the direction to fix this error?
Thanks
Zack
Hello, open an issue on the libvips tracker, it's a better forum for chasing bugs.
Deletehttps://github.com/libvips/libvips/issues