How to make Deep Zoom images with OpenSeaDragon

If you want to show off a huge image on the web, I think the best way is by creating a deep zoom image with Open Sea Dragon (OSD)

I recently built a zoomable map of flags using OSD:

Flagthousand: World’s biggest map of flags

Making the map took years, but the website was pretty easy to set up (with a few snags that I’ve solved), so I wanted to show how I did it.

Using this guide below, you can be up and running in a few minutes:

Step 1: Create your Deep Zoom Image

Install VIPS using homebrew on your terminal. If you don’t have homebrew, here’s a guide to set up homebrew and other basics.

brew install vips

Paste this into your terminal.

Now that you’ve got VIPS installed, you can export your huge image as a JPG from Illustrator. And then run this command below to turn your huge picture into a tiled set. Note that you want to swap out your path/to/your/bigexport.jpg with your path.

Trick: Right click on your file in finder, then hold option ⌥ key, and you’ll see the “Copy” option turns into “Copy as Pathname” which you can then swap out in the code below.

vips dzsave "path/to/your/bigexport.jpg" hugegraphic --tile-size 1022 --suffix .png --overlap 1    

I set mine as PNG because my image is so graphical and can compress it into sharp graphics. If you’re working with a photo, I think it makes more sense to use JPG.

So you’re making a huge photo you would just remove --suffix .png in this code below if you’re exporting it as a .jpg and it may be able to do other files later like webp and avif, but at the time of writing this I couldn’t get those to work.

Step 2: Upload your files

Take those files you just exported, and upload the hugegraphic.dzi file and hugegraphic_files folder to your website server.

Finally, make an html file like this on your server:

<!DOCTYPE html>
<html>
<head>
    <title>Gigapixel Image Viewer</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
        }
        #openseadragon {
            width: 100%;
            height: 100%;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/openseadragon/build/openseadragon/openseadragon.min.js"></script>
</head>
<body>
    <div id="openseadragon"></div>
    <script>
        var viewer = OpenSeadragon({
            id: "openseadragon",
            animationTime: 0.1,
            prefixUrl: "https://cdn.jsdelivr.net/npm/openseadragon/build/openseadragon/images/",
            tileSources: "hugegraphic.dzi"
        });
        viewer.addHandler('open',()=> viewer.world.getItemAt(0).source.hasTransparency = ()=>false );
    </script>
</body>
</html>

And that’s it!

Just save this file as index.html and upload it next to your hugegraphic.dzi file and hugegraphic_files that you uploaded earlier.

There’s a huge range of additional things you can do with these images, including custom buttons, overlays and more that you can explore on the OpenSeaDragon site.


Bonus: Compressing your Tiled Images

One additional thing thing you can do is compress the exported files. This can take about an hour, but it means quicker load time of tiles on your website.

OpenSeaDragon does not (at the time of writing) support the next gen image formats AVIF and WebP. I’m a big fan of AVIF files, and I believe they will support both formats in the upcoming version.

That said, I found I was able to compress the PNG files quite a bit using ImageOptim, which is a great app for quick compression of your pngs and jpgs on mac.

Here’s the settings I used on ImageOptim

You can simple drag the whole folder of tiled png files into it and it will compress it down to 20% or more while keeping transparency.

Fix white lines on PNG with OpenSeaDragon

Here’s one issue I ran into, and I’ve already solved it in the code above. I discovered that using png files with OpenSeaDragon caused it to show white lines between the tiles. It took me a while, but I identified the reason.

There are a couple reasons you might see faint white or black lines between your tiles, but in my case it was because OpenSeaDragon thinks that the PNG file might be transparent. You know, because pngs are often transparent.

So I was getting two anti-aliased images butted up against each other, and seeing that single pixel of transparent edges overlayed on the image. The first thing I tried doing was to change the --overlap 1 in the tile generation above. But doing this just made that line darker or lighter, which made me realize that it was some kind of transparency issue.

Now I’ve already integrated this into the code above, so you shouldn’t encounter this error. This was originally solved by bdrichards who figured out that you can tell the viewer that it doesn’t have transparency:

viewer = OpenSeadragon({...});
viewer.addHandler('open',()=> viewer.world.getItemAt(0).source.hasTransparency = ()=>false );

So yeah, no need to paste that code or anything, it’s already integrated. If you have any questions, feel free to drop a comment or send me an email.

Comments