Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up some tile iteration #1410

Merged
merged 1 commit into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- Remove logic for determining DICOMweb transfer syntax ([#1393](../../pull/1393))
- Speed up tile output ([#1407](../../pull/1407))
- Speed up import time ([#1408](../../pull/1408))
- Speed up some tile iteration by reducing the chance of multiple image decodes ([#1410](../../pull/1410))

### Changes
- Use an enum for priority constants ([#1400](../../pull/1400))
Expand Down
23 changes: 13 additions & 10 deletions large_image/tilesource/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2186,8 +2186,12 @@ def getRegion(self, format=(TILE_FORMAT_IMAGE, ), **kwargs):
y0 = 0
subimage = subimage[:min(subimage.shape[0], regionHeight - y0),
:min(subimage.shape[1], regionWidth - x0)]
image = self._addRegionTileToImage(
image, subimage, x0, y0, regionWidth, regionHeight, tiled, tile, **kwargs)
if tiled:
image = self._addRegionTileToTiled(
image, subimage, x0, y0, regionWidth, regionHeight, tile, **kwargs)
else:
image = self._addRegionTileToImage(
image, subimage, x0, y0, regionWidth, regionHeight, **kwargs)
# Scale if we need to
outWidth = int(math.floor(outWidth))
outHeight = int(math.floor(outHeight))
Expand All @@ -2209,7 +2213,7 @@ def getRegion(self, format=(TILE_FORMAT_IMAGE, ), **kwargs):
return _encodeImage(image, format=format, **kwargs)

def _addRegionTileToImage(
self, image, subimage, x, y, width, height, tiled=False, tile=None, **kwargs):
self, image, subimage, x, y, width, height, tile=None, **kwargs):
"""
Add a subtile to a larger image.

Expand All @@ -2221,12 +2225,8 @@ def _addRegionTileToImage(
the output image.
:param width: the output image size.
:param height: the output image size.
:param tiled: true to generate a tiled output image.
:param tile: the original tile record with the current scale, etc.
:returns: the output image record.
"""
if tiled:
return self._addRegionTileToTiled(image, subimage, x, y, width, height, tile, **kwargs)
if image is None:
if (x, y, width, height) == (0, 0, subimage.shape[1], subimage.shape[0]):
return subimage
Expand Down Expand Up @@ -2473,9 +2473,12 @@ def tileFrames(self, format=(TILE_FORMAT_IMAGE, ), frameList=None,
self.logger.debug(
'Tiling frame %d (%d/%d), offset %dx%d',
frame, idx, len(frameList), offsetX, offsetY)
image = self._addRegionTileToImage(
image, subimage, offsetX, offsetY, outWidth, outHeight, tiled,
tile=tile, **kwargs)
if tiled:
image = self._addRegionTileToTiled(
image, subimage, offsetX, offsetY, outWidth, outHeight, tile, **kwargs)
else:
image = self._addRegionTileToImage(
image, subimage, offsetX, offsetY, outWidth, outHeight, **kwargs)
if tiled:
return self._encodeTiledImage(image, outWidth, outHeight, iterInfo, **kwargs)
return _encodeImage(image, format=format, **kwargs)
Expand Down
7 changes: 6 additions & 1 deletion large_image/tilesource/tiledict.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ def __getitem__(self, key, *args, **kwargs):
if not self.retile:
tileData = self.source.getTile(
self.x, self.y, self.level,
pilImageAllowed=True, numpyAllowed=True,
pilImageAllowed=True,
numpyAllowed='always' if TILE_FORMAT_NUMPY in self.format else True,
sparseFallback=True, frame=self.frame)
if self.crop:
tileData, _ = _imageToNumpy(tileData)
Expand Down Expand Up @@ -217,6 +218,10 @@ def __getitem__(self, key, *args, **kwargs):
raise exceptions.TileSourceError(
'Cannot yield tiles in desired format %r' % (
self.format, ))
elif (TILE_FORMAT_PIL not in self.format and TILE_FORMAT_NUMPY in self.format and
not isinstance(tileData, PIL.Image.Image)):
tileData, _ = _imageToNumpy(tileData)
tileFormat = TILE_FORMAT_NUMPY
else:
tileData = pilData if pilData is not None else _imageToPIL(tileData)
tileFormat = TILE_FORMAT_PIL
Expand Down