Quantcast
Viewing all articles
Browse latest Browse all 8

DeepZoom & SEADragon (I)

There are plenty of times when you want to see something closer, to get a good look at the texture of a sculpture, or find out if that’s a reflection or a scratch on that used car you’re looking at.
Seadragon, implemented as the Deep Zoom feature of Silverlight, allows you to do that. But what if you’re not using the Silverlight platform? That’s what Seadragon Ajax is for.

Seadragon Ajax, written from the ground up in JavaScript, gives you the ability to add a Deep Zoom viewer into your blog, web site, or even your eBay listing.

Let’s see an example of how this works.

First of all, you should be confortable with the DZI (deep zoom image) Schema definition and you should download Microsoft’s DeepZoom composer and, of course, read its manual.

The DeepZoom generated files

Lets suppose you have done all this and generated a new dzi image. Now you should have a directory (I call it ./pagina1) which looks like this:
Image may be NSFW.
Clik here to view.
Deep Zoom Composer results

Let’s take a closer look at this files:

  • dzc_output.xml: this is just a file which shows the XSD used and the image-related data, such as width, height, tilesize, etc…
    <?xml version="1.0" encoding="utf-8"?><Image TileSize="256" Overlap="1" Format="jpg" xmlns="http://schemas.microsoft.com/deepzoom/2008"><Size Width="1820" Height="2312" /></Image>

  • SparseSceneImageGraph: this file contains information related to generation of the image tile.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    <?xml version="1.0"?>
    <SceneGraph version="1">
      <AspectRatio>0,78719723183391</AspectRatio>
      <SceneNode>
        <FileName>C:\Documents and Settings\jrey\Mis documentos\Expression\Deep Zoom Composer Projects\ANTIFON2\Source Images\ms00418_0001.jpg</FileName>
        <x>0</x>
        <y>0</y>
        <Width>1</Width>
        <Height>1</Height>
        <ZOrder>1</ZOrder>
      </SceneNode>
    </SceneGraph>

  • scene.xml: this file indicates how the tiles are composed to obtain complete images. The composed image takes into account the zoom level.
  • dzc_output_files: it contains the tiles in a directory structure like this:
    Image may be NSFW.
    Clik here to view.
    Deep Zoom dzc_output_images folder

Aditional and necessary files

First of all, download and unzip the seadragon viewer and some other files to the parent directory.

You must create the thumbnails for the page too. The parent directory of thumnails must be called mini. For each image we will have two images: for instance, for thumb called pagina1 we will generate the thumbnails pagina1_rest.png and pagina1 _selected.png.

Now, you must build a file (I call it data2.js) which contains a directory structure like the one showed above for each image.
Here is an example of data2.js file which tells SEADragon the title of the image, the thumb, which points to the folder containing the structure (this is, pagina1), the description for that image and where to find the dzi file and the xml contents of that dzi file.

1
2
3
4
5
6
7
8
9
var data = [
    {
        title: 'Antifonario moz&aacute;rabe',
        thumb: 'pagina1',
        desc: 'Antifonario moz&aacute;rabe: p&aacute;gina 1. Procede del Monasterio de San Juan de la Pe&ntilde;a',
        dzi: 'pagina1/dzc_output.xml',
        xml: '<?xml version="1.0" encoding="utf-8"?><Image TileSize="256" Overlap="1" Format="jpg" xmlns="http://schemas.microsoft.com/deepzoom/2008"><Size Width="1820" Height="2312" /></Image>'
	}
]

How to use it in a web page

Now that are familiar to the directory structure and the generated files, lets face the problem of generating an html page which shows the files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
 
<script type="text/javascript">var _sf_startpt=(new Date()).getTime()</script>  
 
		<title>Gallery : Microsoft Live Labs</title>
		<link rel="stylesheet" href="/files/themes/labs/styles.css" type="text/css" media="screen" />
 
 
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://livelabs.com/api/rsd.ashx" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" title="WLWManifest" href="http://livelabs.com/api/wlwmanifest.ashx" />
 
</head>
<body>
 
	<div id="wrapper">
 
	<div id="content_box"> 
		<div id="content_area" >
 
<div id="middle_column" class="content_double_column">
 
<!-- CMS Start -->
<p><style type="text/css">
 
                    #viewer
                    {
                        width: 640px;   
                        height: 480px;  
                        background-color: black;
                        color: white;   /* for error messages, etc. */ 
                        /* border -- on all sides */
                        border: 1px solid black
                    }
 
                    #metadata
                    {
                        /* dimensions */
                        /*width: 564px;   /* plus (1px border + 7px padding) on each side */
			width: 626px;
                        height: 80px;
                        padding: 7px;
 
                        /* color */
                        background-color: #888888;
                        color: white;
 
                        /* border -- don't duplicate border with viewer */
                        border-bottom: 1px solid black;
                        border-left: 1px solid black;
                        border-right: 1px solid black;
                    }
 
                    #metadata #title
                    {
                        font-size: large;
                    }
 
                    #metadata #desc
                    {
                        font-size: small;
                    }
 
                    #desc a:link, 
                    #desc a:visited, 
                    #desc a:hover, 
                    #desc a:active
                    {
                        color:#ffffff;
                        text-decoration:underline;
                    }
 
                    #thumbs
                    {
                        width: 580px;
                        margin-top: 20px;
                    }
 
                    .thumb
                    {
                        position: relative;
                        cursor: pointer;
                    }
 
                </style></p>
<div id="viewer">&nbsp;</div>
<div id="metadata">
<div>
<div id="title">&nbsp;</div>
 
<div id="desc">&nbsp;</div>
</div>
</div>
<div id="thumbs">&nbsp;</div>
<script type="text/javascript" src="ajax/0.8/seadragon-branded.js"></script>
<script type="text/javascript" src="data2.js"></script>
<script type="text/javascript">
 
                    var viewerDiv = document.getElementById('viewer');  
                    var thumbsDiv = document.getElementById('thumbs');
                    var titleDiv = document.getElementById('title');
                    var descDiv = document.getElementById('desc');
 
                    viewerDiv.innerHTML = "";       // for the CMS
 
                    var viewer = new Seadragon.BrandedViewer(viewerDiv);   
                    var selectedItem = null;
		    var thumbsPath = './mini/'; 
 
                    function doOpen(item, anchor)
                    {
                        if(selectedItem)
                            selectedItem.button.src = thumbsPath + selectedItem.thumb + '_rest.png';
 
                        if(item)
                        {
                            viewer.openDzi(item.dzi, item.xml);
                            titleDiv.innerHTML = item.title;
                            descDiv.innerHTML = item.desc;
 
                            item.button.src = thumbsPath + item.thumb + '_selected.png';
                            selectedItem = item;
 
                            if (anchor) {
                                window.location.hash = "#" + item.thumb;
                            }
                        }
                    }
 
                    var count = data.length;
                    var dataMap = {};
                    var a;
                    var x = 0; 
                    var y = 0;
 
                    for (a = 0; a < count; a++)
                    {
                        var item = data[a];
                        var image = document.createElement('img');
 
                        // index item by its thumb name
                        dataMap[item.thumb] = item;
 
                        image.src = thumbsPath + item.thumb + '_rest.png';
                        image.className = "thumb";
                        image.style.left = (16 * x) + 'px';
                        image.style.top = (16 * y) + 'px';
                        image.title = item.title;
 
                        Seadragon.Utils.addEvent(image, "click",
                                Seadragon.Utils.createCallback(null, doOpen, item, true));
 
                        thumbsDiv.appendChild(image);
                        item.button = image;
 
                        x++;
                        if(x >= 9)
                        {
                            x = 0;
                            y++;
                            var br = document.createElement('br');
                            thumbsDiv.appendChild(br);
                        }
                    }
 
                    // if the page's hash is set, open image with that hash
                    // if there is one. otherwise, just open the first image.
                    // note that if there's a hash, it'll begin with #.
                    var hash = (window.location.hash || " ").substr(1);
                    doOpen(dataMap[hash] || data[0], false);    // don't anchor
 
                </script><!-- CMS End -->
 
</div>
</div>
</div>
 
<div id="cap_bottom"></div>
</div>
 
</div><!-- END wrapper -->
 
 
	<!-- SiteCatalyst code version: H.1. Copyright 1997-2005 Omniture, Inc. More info available at http://www.omniture.com -->
  <script language="JavaScript">var s_account="msnportallivelabs";</script>
  <script language="JavaScript" src="http://stj.msn.com/br/om/js/s_code.js"></script>
  <script language="JavaScript">
    <!--
        s.linkInternalFilters="javascript:,.live.,.livelabs.";s.trackExternalLinks=true;
    s.server="livelabs.com";s.channel="livelabs.com";
        s.prop1="livelabs.com";s.prop2="en-us";
        /************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
        var s_code=s.t();if(s_code)document.write(s_code)//-->
  </script>
 
  <script language="JavaScript"> <!-- if(navigator.appVersion.indexOf('MSIE')>=0)document.write(unescape('%3C')+'\!-'+'-')//--> </script>
  <noscript>
    <img src="http://msnportallivelabs.112.2O7.net/b/ss/msnportallivelabs/1/H.1--NS/0" height="1" width="1" border="0" alt="" />
  </noscript>
  <!--/DO NOT REMOVE/-->
  <!-- End SiteCatalyst code version: H.1. -->
	</body>
 
</html>

If you are familiar with javascript and html the code shown is quite self-explainable.

You can see a working example here.

IMHO the thumnails visualization quite ugly, so I decided to add a JCarousel to view these thumnails. This process is quite simple. I will show it how to do it in a subsequent post Image may be NSFW.
Clik here to view.
;)

Want to know more about Deep Zoom images?

Visit the following links:
[1] Detailed mathematical explanation on how the tile algorithm works
[2] Python implementation of Deep Zoom tile images
More interesting info


Viewing all articles
Browse latest Browse all 8

Trending Articles