55from inspect import isawaitable
66from typing import List , Union , Tuple
77from IPython .display import display , HTML
8+ from ngff_zarr import from_ngff_zarr , to_ngff_image , NgffImage
89import uuid
910
1011from ._type_aliases import Gaussians , Style , Image , PointSet
@@ -136,9 +137,10 @@ def __init__(
136137 self , ui_collapsed = True , rotate = False , ui = "pydata-sphinx" , ** add_data_kwargs
137138 ):
138139 """Create a viewer."""
140+ self .stores = {}
139141 self .name = self .__str__ ()
140142 input_data = parse_input_data (add_data_kwargs )
141- data = build_init_data (input_data )
143+ data = build_init_data (input_data , self . stores )
142144 if compare := input_data .get ('compare' ):
143145 data ['compare' ] = compare
144146 if ENVIRONMENT is not Env .HYPHA :
@@ -213,6 +215,7 @@ def set_image(self, image: Image, name: str = 'Image'):
213215 render_type = _detect_render_type (image , 'image' )
214216 if render_type is RenderType .IMAGE :
215217 image = _get_viewer_image (image , label = False )
218+ self .stores [name ] = image
216219 if ENVIRONMENT is Env .HYPHA :
217220 self .image = image
218221 svc_name = f'{ self .workspace } /itkwidgets-server:data-set'
@@ -323,6 +326,36 @@ async def get_current_scale(self):
323326 """
324327 return await self .viewer_rpc .itk_viewer .getLoadedScale ()
325328
329+ @fetch_value
330+ async def get_roi_image (self , scale : int = - 1 , name : str = 'Image' ) -> NgffImage :
331+ """Get the image for the current ROI.
332+
333+ :param scale: scale of the primary image to get the slices for the
334+ current roi. -1, the default, uses the current scale.
335+ :type scale: int
336+ :param name: Name of the loaded image data to use. 'Image', the
337+ default, selects the first loaded image.
338+ :type name: str
339+
340+ :return: roi_image
341+ :rtype: NgffImage
342+ """
343+ roi_slices = await self .get_roi_slice (scale )
344+ roi_region = await self .get_roi_region ()
345+ if store := self .stores .get (name ):
346+ multiscales = from_ngff_zarr (store )
347+ loaded_image = multiscales .images [scale ]
348+ roi_data = loaded_image .data [roi_slices ]
349+ return to_ngff_image (
350+ roi_data ,
351+ dims = loaded_image .dims ,
352+ scale = loaded_image .scale ,
353+ translation = roi_region [0 ],
354+ name = name ,
355+ axes_units = loaded_image .axes_units
356+ )
357+ raise ValueError (f'No image data found for { name } .' )
358+
326359 @fetch_value
327360 async def get_roi_region (self ):
328361 """Get the current region of interest in world / physical space.
@@ -339,7 +372,7 @@ async def get_roi_region(self):
339372 return [{ 'x' : x0 , 'y' : y0 , 'z' : z0 }, { 'x' : x1 , 'y' : y1 , 'z' : z1 }]
340373
341374 @fetch_value
342- async def get_roi_slice (self , scale = - 1 ):
375+ async def get_roi_slice (self , scale : int = - 1 ):
343376 """Get the current region of interest as Python slice objects for the
344377 current resolution of the primary image. The result is in the order:
345378
@@ -395,6 +428,7 @@ def set_label_image(self, label_image: Image):
395428 render_type = _detect_render_type (label_image , 'image' )
396429 if render_type is RenderType .IMAGE :
397430 label_image = _get_viewer_image (label_image , label = True )
431+ self .stores ['LabelImage' ] = label_image
398432 if ENVIRONMENT is Env .HYPHA :
399433 self .label_image = label_image
400434 svc_name = f"{ self .workspace } /itkwidgets-server:data-set"
0 commit comments