diff --git a/CHANGELOG.md b/CHANGELOG.md index 5efe17562..ec08ceee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Improvements - Read config values from the environment variables ([#1422](../../pull/1422)) +- Optimizing when reading arrays rather than images from tiff files ([#1423](../../pull/1423)) ## 1.27.0 diff --git a/sources/ometiff/large_image_source_ometiff/__init__.py b/sources/ometiff/large_image_source_ometiff/__init__.py index 296c64485..29126bc7a 100644 --- a/sources/ometiff/large_image_source_ometiff/__init__.py +++ b/sources/ometiff/large_image_source_ometiff/__init__.py @@ -352,7 +352,7 @@ def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False, numpyAllowed=numpyAllowed, sparseFallback=sparseFallback, **kwargs) try: - tile = dir.getTile(x, y) + tile = dir.getTile(x, y, asarray=numpyAllowed == 'always') format = 'JPEG' if isinstance(tile, PIL.Image.Image): format = TILE_FORMAT_PIL diff --git a/sources/tiff/large_image_source_tiff/__init__.py b/sources/tiff/large_image_source_tiff/__init__.py index 33b21fdb5..a75417b63 100644 --- a/sources/tiff/large_image_source_tiff/__init__.py +++ b/sources/tiff/large_image_source_tiff/__init__.py @@ -645,7 +645,7 @@ def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False, allowStyle = False format = TILE_FORMAT_PIL else: - tile = dir.getTile(x, y) + tile = dir.getTile(x, y, asarray=numpyAllowed == 'always') format = 'JPEG' if isinstance(tile, PIL.Image.Image): format = TILE_FORMAT_PIL diff --git a/sources/tiff/large_image_source_tiff/tiff_reader.py b/sources/tiff/large_image_source_tiff/tiff_reader.py index 61bf9d11e..a974d7c8b 100644 --- a/sources/tiff/large_image_source_tiff/tiff_reader.py +++ b/sources/tiff/large_image_source_tiff/tiff_reader.py @@ -754,7 +754,7 @@ def imageHeight(self): def pixelInfo(self): return self._pixelInfo - def getTile(self, x, y): + def getTile(self, x, y, asarray=False): """ Get the complete JPEG image from a tile. @@ -762,6 +762,8 @@ def getTile(self, x, y): :type x: int :param y: The row index of the desired tile. :type y: int + :param asarray: If True, read jpeg compressed images as arrays. + :type asarray: boolean :return: either a buffer with a JPEG or a PIL image. :rtype: bytes :raises: InvalidOperationTiffError or IOTiffError @@ -774,11 +776,14 @@ def getTile(self, x, y): tileNum = self._toTileNum(x, y) if (not self._tiffInfo.get('istiled') or - self._tiffInfo.get('compression') not in ( - libtiff_ctypes.COMPRESSION_JPEG, 33003, 33005, 34712) or + self._tiffInfo.get('compression') not in { + libtiff_ctypes.COMPRESSION_JPEG, 33003, 33005, 34712} or self._tiffInfo.get('bitspersample') != 8 or self._tiffInfo.get('sampleformat') not in { - None, libtiff_ctypes.SAMPLEFORMAT_UINT}): + None, libtiff_ctypes.SAMPLEFORMAT_UINT} or + (asarray and self._tiffInfo.get('compression') not in {33003, 33005, 34712} and ( + self._tiffInfo.get('compression') != libtiff_ctypes.COMPRESSION_JPEG or + self._tiffInfo.get('photometric') != libtiff_ctypes.PHOTOMETRIC_YCBCR))): return self._getUncompressedTile(tileNum) imageBuffer = io.BytesIO()