Skip to content

Commit

Permalink
Add an option to convert a single frame of a multiframe image.
Browse files Browse the repository at this point in the history
  • Loading branch information
manthey committed Mar 29, 2021
1 parent 7905c39 commit cee4a89
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
7 changes: 3 additions & 4 deletions girder/girder_large_image/rest/tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,9 @@ def createTiles(self, item, params):
required=False)
.param('tileSize', 'Tile size', dataType='int', default=256,
required=False)
.param('frame', 'Single frame number. If the source is a multiframe '
'image and this value is specified, only the selected frame is '
'included in the result.', dataType='int', default=None,
required=False)
.param('onlyFrame', 'Only convert a specific 0-based frame of a '
'multiframe file. If not specified, all frames are converted.',
dataType='int', required=False)
.param('compression', 'Internal compression format', required=False,
enum=['none', 'jpeg', 'deflate', 'lzw', 'zstd', 'packbits', 'webp', 'jp2k'])
.param('quality', 'JPEG compression quality where 0 is small and 100 '
Expand Down
11 changes: 11 additions & 0 deletions test/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,17 @@ def testConvertFromMultiframeImageNoSubIFDS(tmpdir):
assert len(info['ifds']) == 15


def testConvertFromMultiframeImageOnlyOneFrame(tmpdir):
imagePath = utilities.externaldata('data/sample.ome.tif.sha512')
outputPath = os.path.join(tmpdir, 'out.tiff')
large_image_converter.convert(imagePath, outputPath, onlyFrame=2)
source = large_image_source_tiff.open(outputPath)
metadata = source.getMetadata()
assert metadata['levels'] == 5
info = tifftools.read_tiff(outputPath)
assert len(info['ifds']) == 5


# Test main program

def testConverterMain(tmpdir):
Expand Down
12 changes: 11 additions & 1 deletion utilities/converter/large_image_converter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ def _generate_multiframe_tiff(inputPath, outputPath, tempPath, lidata, **kwargs)
imageSizes = []
tasks = []
pool = _get_thread_pool(**kwargs)
onlyFrame = int(kwargs.get('onlyFrame')) if str(kwargs.get('onlyFrame')).isdigit() else None
frame = 0
# Process each image separately to pyramidize it
for page in range(pages):
subInputPath = inputPath + '[page=%d]' % page
Expand All @@ -168,6 +170,9 @@ def _generate_multiframe_tiff(inputPath, outputPath, tempPath, lidata, **kwargs)
os.unlink(path)
width = subImage.width
height = subImage.height
frame += 1
if onlyFrame is not None and onlyFrame + 1 != frame:
continue
subOutputPath = tempPath + '-%d-%s.tiff' % (
page + 1, time.strftime('%Y%m%d-%H%M%S'))
_pool_add(tasks, (pool.submit(
Expand Down Expand Up @@ -512,7 +517,12 @@ def _convert_large_image(inputPath, outputPath, tempPath, lidata, **kwargs):
outputList = []
tasks = []
pool = _get_thread_pool(**kwargs)
for frame in range(numFrames):
startFrame = 0
endFrame = numFrames
if kwargs.get('onlyFrame') is not None and str(kwargs.get('onlyFrame')):
startFrame = int(kwargs.get('onlyFrame'))
endFrame = startFrame + 1
for frame in range(startFrame, endFrame):
frameOutputPath = tempPath + '-%d-%s.tiff' % (
frame + 1, time.strftime('%Y%m%d-%H%M%S'))
_pool_add(tasks, (pool.submit(
Expand Down
4 changes: 4 additions & 0 deletions utilities/converter/large_image_converter/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def get_parser():
parser.add_argument(
'--subifds', action='store_true', dest='subifds', default=None,
help='When writing multiframe files, use subifds.')
parser.add_argument(
'--frame', dest='onlyFrame', default=None, type=int,
help='When handling a multiframe file, only output a single frame. '
'This is the zero-based frame number.')
parser.add_argument(
'--compression', '-c',
choices=[
Expand Down

0 comments on commit cee4a89

Please sign in to comment.