Skip to content

Commit 8f0adee

Browse files
committed
deepzoom-tile: Also tile associated images if -r option specified
1 parent b8a30c6 commit 8f0adee

File tree

1 file changed

+48
-13
lines changed

1 file changed

+48
-13
lines changed

examples/deepzoom/deepzoom-tile.py

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"""An example program to generate a Deep Zoom directory tree from a slide."""
2222

2323
from multiprocessing import Process, JoinableQueue
24-
from openslide import open_slide
24+
from openslide import open_slide, ImageSlide
2525
from openslide.deepzoom import DeepZoomGenerator
2626
from optparse import OptionParser
2727
import os
@@ -35,26 +35,39 @@ def __init__(self, queue, slidepath, tile_size, overlap):
3535
self._slidepath = slidepath
3636
self._tile_size = tile_size
3737
self._overlap = overlap
38+
self._slide = None
3839

3940
def run(self):
40-
dz = DeepZoomGenerator(open_slide(self._slidepath), self._tile_size,
41-
self._overlap)
41+
self._slide = open_slide(self._slidepath)
42+
last_associated = None
43+
dz = self._get_dz()
4244
while True:
4345
data = self._queue.get()
4446
if data is None:
4547
self._queue.task_done()
4648
break
47-
level, address, outfile = data
49+
associated, level, address, outfile = data
50+
if last_associated != associated:
51+
dz = self._get_dz(associated)
52+
last_associated = associated
4853
tile = dz.get_tile(level, address)
4954
tile.save(outfile, optimize=True, quality=90)
5055
self._queue.task_done()
5156

57+
def _get_dz(self, associated=None):
58+
if associated is not None:
59+
image = ImageSlide(self._slide.associated_images[associated])
60+
else:
61+
image = self._slide
62+
return DeepZoomGenerator(image, self._tile_size, self._overlap)
63+
5264

5365
class DeepZoomImageTiler(object):
54-
def __init__(self, dz, basename, format, queue):
66+
def __init__(self, dz, basename, format, associated, queue):
5567
self._dz = dz
5668
self._basename = basename
5769
self._format = format
70+
self._associated = associated
5871
self._queue = queue
5972
self._processed = 0
6073

@@ -73,14 +86,16 @@ def _write_tiles(self):
7386
tilename = os.path.join(tiledir, '%d_%d.%s' % (
7487
col, row, self._format))
7588
if not os.path.exists(tilename):
76-
self._queue.put((level, (col, row), tilename))
89+
self._queue.put((self._associated, level, (col, row),
90+
tilename))
7791
self._tile_done()
7892

7993
def _tile_done(self):
8094
self._processed += 1
8195
count, total = self._processed, self._dz.tile_count
8296
if count % 100 == 0 or count == total:
83-
print >> sys.stderr, "Wrote %d/%d tiles\r" % (count, total),
97+
print >> sys.stderr, "Tiling %s: wrote %d/%d tiles\r" % (
98+
self._associated or 'slide', count, total),
8499
if count == total:
85100
print
86101

@@ -91,24 +106,40 @@ def _write_dzi(self):
91106

92107
class DeepZoomStaticTiler(object):
93108
def __init__(self, slidepath, basename, format, tile_size, overlap,
94-
workers):
109+
workers, with_viewer):
95110
self._slide = open_slide(slidepath)
96111
self._basename = basename
97112
self._format = format
98113
self._tile_size = tile_size
99114
self._overlap = overlap
100115
self._queue = JoinableQueue(2 * workers)
101116
self._workers = workers
117+
self._with_viewer = with_viewer
102118
for _i in range(workers):
103119
TileWorker(self._queue, slidepath, tile_size, overlap).start()
104120

105121
def run(self):
106-
dz = DeepZoomGenerator(self._slide, self._tile_size, self._overlap)
107-
tiler = DeepZoomImageTiler(dz, self._basename, self._format,
108-
self._queue)
109-
tiler.run()
122+
self._run_image()
123+
if self._with_viewer:
124+
for name in self._slide.associated_images:
125+
self._run_image(name)
110126
self._shutdown()
111127

128+
def _run_image(self, associated=None):
129+
"""Run a single image from self._slide."""
130+
if associated is None:
131+
image = self._slide
132+
if self._with_viewer:
133+
basename = os.path.join(self._basename, 'slide')
134+
else:
135+
basename = self._basename
136+
else:
137+
image = ImageSlide(self._slide.associated_images[associated])
138+
basename = os.path.join(self._basename, associated)
139+
dz = DeepZoomGenerator(image, self._tile_size, self._overlap)
140+
DeepZoomImageTiler(dz, basename, self._format, associated,
141+
self._queue).run()
142+
112143
def _shutdown(self):
113144
for _i in range(self._workers):
114145
self._queue.put(None)
@@ -128,6 +159,9 @@ def _shutdown(self):
128159
help='number of worker processes to start [4]')
129160
parser.add_option('-o', '--output', metavar='NAME', dest='basename',
130161
help='base name of output file')
162+
parser.add_option('-r', '--viewer', dest='with_viewer',
163+
action='store_true',
164+
help='generate directory tree with HTML viewer')
131165
parser.add_option('-s', '--size', metavar='PIXELS', dest='tile_size',
132166
type='int', default=256,
133167
help='tile size [256]')
@@ -141,4 +175,5 @@ def _shutdown(self):
141175
opts.basename = os.path.splitext(os.path.basename(slidepath))[0]
142176

143177
DeepZoomStaticTiler(slidepath, opts.basename, opts.format,
144-
opts.tile_size, opts.overlap, opts.workers).run()
178+
opts.tile_size, opts.overlap, opts.workers,
179+
opts.with_viewer).run()

0 commit comments

Comments
 (0)