This is an old revision of the document!


Deep Zoom

Blocks has at time of writing this note not any native feature for curating and publich deep zoom imagery. This application note shows how a web block can be used to present deep zoom images using a few lines of custom html and content curated with a 3rd party application.

Try deep zoom

Download this block, import it to your Blocks system using the import feature in the editor. This is a minimalistic self-contained custom web block that contains the components required to run the example.

If you rather try it out with a mobile device and a visitor spot, you may want to use this block that example is made in portrait orientation and uses more appropriate resolution to make the panning and zooming smooth on mobile devices.

How does it work

This block has a custom component the is stored inside the example blocks folder. This makes it self-contained and can be distributed via the editor. Open the zip file in finder/explorer and look at the internals.

You should see something like this:

Where the files Spec.pixi, Meta,json and the directory media is standard blocks components. Our custom directory is the interesting bit here.

Index.html this is what we reference to in the web block.

Openseadragon.min.js is the js library used to create the deep zoom functionality.

Image folder is images used by the library if navigation buttons is enable in the html file.

Out is where we find our deep zoom media. The media has been processed into a dzi package. This is a pyramid format often used by ie. digital maps where it is beneficial to zoom large distances. It is simply a method to avoid loading a single very large file, instead they are shopped up in a grid and there are several grids stacked on top of each other to create the zoom levels. This creates kind of a pyramid, where the top is the first image you see in the viewer. This way the viewer can automatically show just a few of the images at any given time in order to conserve loading time, memory use and to make sure the viewer is capable to handle any user interaction with heigh framerate.

A dzi package has two components, a description file, in our example it is hr.dzi and a folder prefixed with the same name where all the processed images is stored.

How to create such package is covered later in this article.

The code inside the index.html file is simple.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
	<style>
		html, body {
			margin:0;
			padding: 0;
		}
		#openseadragon1 {
			width: 1920px; height: 1080px;
		}
	</style>
</head>
<body>
<div id="openseadragon1"></div>
<script src="openseadragon.min.js"></script>
<script type="text/javascript">

    var viewer = OpenSeadragon({
        id: "openseadragon1",
        prefixUrl: "images/",
        tileSources: "out/hr.dzi",
	showNavigationControl: false
	});

</script>
</body>
</html>

At the top we got the usual HTML document header followed by a head element with some inline styling.

The size of the seadragon viewer is specified here.

		#openseadragon1 {
			width: 1920px; height: 1080px;
		}

The the html element where the viewer is displayed is here.

Finally we got the script part where the first line references the external library and the rest initialises the viewer with its settings.

<code><div id="openseadragon1"></div>

<script type="text/javascript">

  var viewer = OpenSeadragon({
      id: "openseadragon1",
      prefixUrl: "images/",
      tileSources: "out/hr.dzi",
showNavigationControl: false
});

</script> </code>

The full list of options to experiment with is available here.

Prepare the images for deep zoom

A computer with java installed and the java default path enabled in the environment variables. This can be tested by open a terminal and type java and hit enter. If java is present and the path is in environment variables, java should start and a list of available options is presented in the terminal. We have used the java application Pyramido-cli to prepare the deep zoom content.

The tool can be downloaded here. Credits to the employees at National Institute of Standards and Technology for writing and sharing the program.

Unpack the zipfile om your hard drive. Inside you will find a high-resolution example file. The tool support both jpg and png. It is important that the colour format is RGB 8bit. If it is not, the image must be converted by open it and change the settings in a photo editor.

Browse to the folder where the tool is located.

Inside the folder you can find a process.bat file to use with windows and process.sh file to use with unix based computers such as mac and linux. The scripts are just a one-liner with the command line instruction below to process the example file hr.jpg and put the output in the out folder. Double click the script to start the process.

As an alternative a terminal can be opened in the tool’s directory. Run the following command in the terminal window.

 java -Xms1G -jar pyramidio-cli.jar --tileSize 510 -i hr.jpg -o out

To select another source file just copy the file to the same directory as the tool and change hr.jpg in the command to the name of your new file. The result will end up in the out directory prefixed with the source file name.

Copy the resulting file and folder from inside the out directory to your deep zoom block's custom/out directory.

The file name of the new dzi source must be specified in the custom blocks index.html file. Find the line specifying the tileSource and change to your new .dzi file name.

A block example using multiple dzi source files

This example uses a modified version of the custom index.html file that accepts query parameters. This make is possible to control the tileSource form by sending query parameters. A query parameter is the options that can be sent to a website using a ? to tell the webpage that there are query parameters to follow. One can use multiple query parameters separated by &.

The example block can be downloaded from here.

The block is a composition at top-level. Inside a couple of small compositions that builds our menu. The book that acts as an overlay that loads the webpage controlled by the buttons. The buttons trigs two actions each, one that set a parameter to a string, the value is the path to the tileSource. Ie. out/hr.dzi and the other changes the overlay book to page2 to expose the web block with the zoom content. When the user closes with the close button the menu is exposed, and a new selection can be made by the user.

The web block uses a useful feature that enables us to pass the value of Blocks parameters on to the custom web page as a query parameter. In this case we pass the tileSource parameter value we set with the buttons. Multiple parameters value can be passed with this method separated with a comma.

Query parameters code example

This example can also be useful to demonstrate the code required to use query parameters in pages. Compare to the simple example from the beginning of this application note.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
	<style>
		html, body {
			margin:0;
			padding: 0;
		}
		#openseadragon1 {
			width: 800px; height: 800px;
		}
	</style>
</head>
<body>
<div id="openseadragon1"></div>
<script src="openseadragon.min.js"></script>
<script type="text/javascript">

/**
 * Get the set of query params specified in URL, building it if not yet done.
 */
function getQueryParams() {
	if (!queryParams) {
		const query = window.location.search.substring(1);
		const vars = query.split("&");
		const qParams = {};
		if (vars.length > 0 && vars[0].length > 0) {	// Got some fish
			for (var i = 0; i < vars.length; i++) {
				const pair = vars[i].split('=');
				var value = pair[1];
				value = value.split('?')[0];	// Discard any garbage added by SSSP v2
				qParams[pair[0]] = value;
			}
		}
		queryParams = qParams;
	}
	return queryParams;
}
var queryParams;	// Use ONLY through getQueryParams



    var viewer = OpenSeadragon({
        id: "openseadragon1",
        prefixUrl: "images/",
        tileSources: getQueryParams()['tileSources'] || "out/hr.dzi",
				minZoomLevel: getQueryParams()['minZoomLevel'],
				maxZoomLevel: getQueryParams()['maxZoomLevel'],
				minZoomImageRatio: getQueryParams()['minZoomImageRatio'] || 1,
				maxZoomPixelRatio: getQueryParams()['maxZoomPixelRatio'] || 1,
				visibilityRatio: getQueryParams()['visibilityRatio'] || 1,
				showNavigationControl: false
	});




</script>
</body>
</html>