@@ -329,21 +329,68 @@ def close(self) -> None:
329329 def is_started (self ) -> bool : return self ._is_started
330330 def is_closed (self ) -> bool : return self ._is_closed
331331
332- def get_rt_output (self ) -> np .ndarray :
332+ def get_rt_output (self , bps : Union [ ChannelDepth , str ] = ChannelDepth . Bps8 ) -> np .ndarray :
333333 """Return a copy of the output image.
334+
335+ The image data type is specified with the ``bps`` argument. 8 bit per channel data,
336+ ``numpy.uint8``, is returned by default. Use ``Bps16`` value to read the image in
337+ 16 bit per channel depth, ``numpy.uint16``. Use ``Bps32`` value to read the HDR image
338+ in 32 bit per channel format, ``numpy.float32``.
339+
340+ Channels ordering is RGBA, with constant values in the alpha channel (100% opaque,
341+ to be used in the future releases).
334342
335343 Safe to call at any time, from any thread.
336344
345+ Parameters
346+ ----------
347+ bps : ChannelDepth enum or string, optional
348+ Color depth.
349+
337350 Returns
338351 -------
339352 out : ndarray
340- RGBA array of shape (height, width, 4) and type ``numpy.uint8``.
353+ RGBA array of shape (height, width, 4) and type corresponding to ``bps`` argument.
354+
355+ See Also
356+ --------
357+ :class:`plotoptix.enums.ChannelDepth`
341358 """
342359 assert self ._is_started , "Raytracing output not running."
343- with self ._padlock :
344- a = self ._img_rgba .copy ()
360+
361+ if isinstance (bps , str ): bps = ChannelDepth [bps ]
362+
363+ a = None
364+
365+ try :
366+ self ._padlock .acquire ()
367+
368+ ok = True
369+
370+ if bps == ChannelDepth .Bps8 :
371+ a = self ._img_rgba .copy ()
372+ elif bps == ChannelDepth .Bps16 :
373+ a = np .ascontiguousarray (np .zeros ((self ._height , self ._width , 4 ), dtype = np .uint16 ))
374+ ok = self ._optix .get_output (a .ctypes .data , a .nbytes , bps .value )
375+ elif bps == ChannelDepth .Bps32 :
376+ a = np .ascontiguousarray (np .zeros ((self ._height , self ._width , 4 ), dtype = np .float32 ))
377+ ok = self ._optix .get_output (a .ctypes .data , a .nbytes , bps .value )
378+
379+ if not ok :
380+ msg = "Image not saveed."
381+ self ._logger .error (msg )
382+ if self ._raise_on_error : raise ValueError (msg )
383+
384+ except Exception as e :
385+ self ._logger .error (str (e ))
386+ if self ._raise_on_error : raise
387+
388+ finally :
389+ self ._padlock .release ()
390+
345391 return a
346392
393+
347394 def resize (self , width : Optional [int ] = None , height : Optional [int ] = None ) -> None :
348395 """Change dimensions of the raytracing output.
349396
@@ -1642,7 +1689,7 @@ def save_scene(self, file_name: str) -> None:
16421689 self ._padlock .acquire ()
16431690
16441691 if not self ._optix .save_scene_to_file (file_name ):
1645- msg = "Scene not saveed ."
1692+ msg = "Scene not saved ."
16461693 self ._logger .error (msg )
16471694 if self ._raise_on_error : raise ValueError (msg )
16481695
@@ -1654,22 +1701,45 @@ def save_scene(self, file_name: str) -> None:
16541701 self ._padlock .release ()
16551702
16561703
1657- def save_image (self , file_name : str ) -> None :
1704+ def save_image (self , file_name : str ,
1705+ bps : Union [ChannelDepth , str ] = ChannelDepth .Bps8 ) -> None :
16581706 """Save current image to file.
16591707
1660- Save current content of the image buffer to file. Accepted formats,
1661- recognized by the extension used in the ``file_name``, are bmp, gif,
1662- png, jpg, and tif. Existing files are overwritten.
1708+ Save current content of the image buffer to a file. Accepted formats,
1709+ recognized by the extension used in the ``file_name``, are:
1710+
1711+ - bmp, gif, png, jpg, and tif for 8bps color depth,
1712+ - png, and tif for 16bps color depth,
1713+ - tif for 32bps hdr images.
1714+
1715+ Existing files are overwritten.
16631716
16641717 Parameters
16651718 ----------
16661719 file_name : str
16671720 Output file name.
1721+ bps : ChannelDepth enum or string, optional
1722+ Color depth.
1723+
1724+ See Also
1725+ --------
1726+ :class:`plotoptix.enums.ChannelDepth`
16681727 """
1728+ if isinstance (bps , str ): bps = ChannelDepth [bps ]
1729+
16691730 try :
16701731 self ._padlock .acquire ()
16711732
1672- if not self ._optix .save_image_to_file (file_name ):
1733+ if bps == ChannelDepth .Bps8 :
1734+ ok = self ._optix .save_image_to_file (file_name )
1735+ elif bps == ChannelDepth .Bps16 :
1736+ ok = self ._optix .save_image_to_file_16bps (file_name )
1737+ elif bps == ChannelDepth .Bps32 :
1738+ ok = self ._optix .save_image_to_file_32bps (file_name )
1739+ else :
1740+ ok = False
1741+
1742+ if not ok :
16731743 msg = "Image not saveed."
16741744 self ._logger .error (msg )
16751745 if self ._raise_on_error : raise ValueError (msg )
0 commit comments