2009年1月21日 星期三

Viewing Large Images - OpenLayers, GSIV, ModestMaps, DeepZoom, and Python







Viewing Large Images - OpenLayers, GSIV, ModestMaps, DeepZoom, and Python






Lately
I’ve been experimenting with displaying very large images on the
internet via a web browser, with pan and zoom functionality. The guts
of this functionality are the same regardless of implementation. On the
server, a tile cutter processes a large image, and constructs an image
pyramid. The image pyramid is a hierarchical structure composed of n
levels of the same image at different resolutions. Starting with the
bottom level as the original image, each successive level reduces the
image size by half, and the process is repeated log_2( max( width,
height)) times until finally an image of only 1 pixel (average of
entire image) is generated as the top of the pyramid. Each level’s
image is split into a set of fixed size tiles. A web browser client
implementation ( flash, ajax, etc) constructs  a zoom interface, that
responds to zoom in events by moving the viewport progressively further
down the pyramid, showing tile images of the larger resolution to give
the effect of zooming into an image. A nice illustrated write up of the
concept can be found here. I’ve probably made it sound more complicated than it really is.


The initial implementation I was working with utilized OpenLayers, which implements a client for accessing OpenGIS Web Feature Servers (WFS) and Web Mapping Servers (WMS).
Unfortunately the size of the library seems to be constantly increasing
(~200K in the last year) and currently weighs in at 560K uncompressed,
and requires a special implementation to serve up the tile images, ie.
a WMS Compliant system, in this case TileCache. For scaling and efficiency purposes, I’d much prefer to directly serve these images off a CDN, disk (nginx), or via varnish
and bypass any application code. Additionally the sheer size of the
OpenLayers code was unwieldy for the integrations requirements I had,
which did not include any GIS functionality.


Surveying the land for other non-commercial image viewers, turned up a few of interest. GSIV
( Giant Scalable Image Viewer), was a fairly basic but capable
javascript based viewer, that fit my requirements bill, small size at
26Kb uncompressed, and focused on pan and zoom functionality (demo).
However as a project it appears to be abandoned, and hasn’t been
touched in two years, although several patches have been submitted
which retrofit the implementation using jquery are extant.


I came across ModestMaps next, which is a flash (2 & 3 ) based implementation, with a small size (demo).
One nice feature of modest maps, is that it performs interpolation
between successive levels giving a smooth zoom experience to an end
user unlike somewhat jerky experience that GSIV produced. Unfortunately
being flash based meant a whole different chain of development tools. I
looked around at what was available for an opensource flash compiler
toolchain and found MTASC (Motion Twin Action Script Compiler ) and Haxe.
In the end i decided against it, partly due to its GIS focus, and the
customization/ maintenance cost for developing on propretiary platform
(Flash). Despite that, i think its the best of the opensource viewer
implementations if your already have/use an adobe flash development
stack.


I was set on using GSIV, and then i came across a blurb on ajaxian
about Seadragon Ajax and Deep Zoom from Microsoft’s Live Labs.
Microsoft’s done some impressive work with image manipulation over the
last few years. The PhotoSynth TED talk is one of the most impressive technology demos i’ve seen to date. Deep Zoom is a SilverLight technology ( more propretiary platform lockin), that allows for multiscale image zooming with smooth zooming. The Seadragon Ajax
is a javascript implementation of the same functionality in a 154k
library ( 20k minimized and gzipped). It fit the bill perfectly,
standards (javascript) based, image zoom and pan, with a great user
experience. One problem unlike all the other tools mentioned here,
which have python based tile cutting implementations, Deep Zoom was
utilizing a Windows only based program to process images and cut tiles.
I had a couple of hundred gigabytes of images to cut, and not a windows
system in sight. But based on this excellent blog write up by Daniel Gasiencia,
I constructed a python program using PIL that can be used as a command
line tool or library for constructing Deep Zoom Compatible image
pyramids. It can be found here,
hopefully its useful to others. As a bonus, it runs in a fraction of
the memory (1/6 by my measurements) needed by the GSIV image tile
cutter and faster as well ( 100 images in 5m vs 1.25hr). Unfortunately
the Seadragon Ajax Library is not opensource, but non commercial usage
seems to be okay with the license, and i’ll give it over to some
lawyers to figure it out.


To process the several hundred gigabytes of images, i utilized this library and wrote a batch driver utilizing  pyprocessing remote queues, a small zc.buildout and cloudcontrol to process the images across a cluster, but thats left as an implementation detail for the reader

沒有留言: