Skip to content

Commit

Permalink
Merge pull request #1770 from girder/more-vips
Browse files Browse the repository at this point in the history
Be slightly more flexible in reading multi-frames from vips
  • Loading branch information
manthey authored Jan 10, 2025
2 parents b0916f0 + c0951cf commit a463c19
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Improvements

- Better report if rasterized vector files are geospatial ([#1769](../../pull/1769))
- Provide some latitude in vips multiframe detection ([#1770](../../pull/1770))

## 1.30.6

Expand Down
1 change: 1 addition & 0 deletions girder/test_girder/test_web_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def testWebClient(boundServer, fsAssetstore, db, spec, girderWorker):
runWebClientTest(boundServer, spec, 15000)


@pytest.mark.singular
@pytest.mark.usefixtures('unbindLargeImage')
@pytest.mark.plugin('large_image')
@pytest.mark.parametrize('spec', [
Expand Down
20 changes: 16 additions & 4 deletions sources/vips/large_image_source_vips/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class VipsFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):

_tileSize = 256

def __init__(self, path, **kwargs):
def __init__(self, path, **kwargs): # noqa
"""
Initialize the tile class. See the base class for other available
parameters.
Expand All @@ -70,6 +70,7 @@ def __init__(self, path, **kwargs):
super().__init__(path, **kwargs)
self.addKnownExtensions()

self._suffix = ''
if str(path).startswith(NEW_IMAGE_PATH_FLAG):
self._initNew(**kwargs)
return
Expand All @@ -85,6 +86,11 @@ def __init__(self, path, **kwargs):
raise TileSourceFileNotFoundError(self._largeImagePath) from None
msg = 'File cannot be opened via pyvips'
raise TileSourceError(msg)
# Ask pdfs to render at a higher resolution
if ('vips-loader' in self._image.get_fields() and
self._image.get('vips-loader') in {'pdfload'}):
self._suffix = ',dpi=144'
self._image = pyvips.Image.new_from_file(self._largeImagePath + '[dpi=300]')
self.sizeX = self._image.width
self.sizeY = self._image.height
self.tileWidth = self.tileHeight = self._tileSize
Expand All @@ -93,7 +99,7 @@ def __init__(self, path, **kwargs):
pages = self._image.get('n-pages')
self._frames = [0]
for page in range(1, pages):
subInputPath = self._largeImagePath + '[page=%d]' % page
subInputPath = self._largeImagePath + f'[page={page}{self._suffix}]'
with _newFromFileLock:
try:
subImage = pyvips.Image.new_from_file(subInputPath)
Expand All @@ -102,6 +108,10 @@ def __init__(self, path, **kwargs):
if subImage.width == self.sizeX and subImage.height == self.sizeY:
self._frames.append(page)
continue
if (self.sizeX - 16 < subImage.width <= self.sizeX and
self.sizeY - 16 < subImage.height <= self.sizeY):
self._frames.append(page)
continue
if subImage.width * subImage.height < self.sizeX * self.sizeY:
continue
self._frames = [page]
Expand Down Expand Up @@ -197,7 +207,7 @@ def _getFrameImage(self, frame=0):
if frame > 0:
with self._frameLock:
if frame not in self._recentFrames:
subpath = self._largeImagePath + '[page=%d]' % self._frames[frame]
subpath = self._largeImagePath + f'[page={self._frames[frame]}{self._suffix}]'
with _newFromFileLock:
img = pyvips.Image.new_from_file(subpath)
self._recentFrames[frame] = img
Expand All @@ -223,7 +233,9 @@ def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False, **kwargs):
self._xyzInRange(x, y, z, frame, len(self._frames))
img = self._getFrameImage(frame)
x0, y0, x1, y1, step = self._xyzToCorners(x, y, z)
tileimg = img.crop(x0, y0, x1 - x0, y1 - y0)
tileimg = img.crop(min(x0, img.width), min(y0, img.height),
min(x1, img.width) - min(x0, img.width),
min(y1, img.height) - min(y0, img.height))
try:
if step != 1:
tileimg = tileimg.resize(1.0 / step, kernel=pyvips.enums.Kernel.NEAREST, gap=0)
Expand Down

0 comments on commit a463c19

Please sign in to comment.