Skip to content

Commit b7f18cf

Browse files
committed
Clean up sample loader.
1 parent 52b3dd3 commit b7f18cf

1 file changed

Lines changed: 55 additions & 29 deletions

File tree

python/Scripts/OIIOLoader.py

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@
44
This module provides a MaterialX-compatible ImageLoader implementation using OpenImageIO (OIIO).
55
The test will test loading an image, save it out, and optionally previewing it.
66
7+
Steps:
8+
1. Create an OIIOLoader which is derived from the ImageLoader interface class.
9+
2. Create a new ImageHandler and register the loader with it.
10+
3. Request to acquire an image using the ImageHandler. An EXR image is requested.
11+
4. OIIOLoader will return supported extensions and match the requested image format.
12+
5. As such the OIIOLoader will be requested to load in the EXR image, convert the
13+
data and return a MaterialX Image.
14+
6. Try to acquire the image again. This should returnt the cached MaterialX Image.
15+
7. Save the image back to disk in the original format.
16+
17+
The image can optionally be previewed after load before save.
18+
719
- Python Dependencies:
820
- OpenImageIO (version 3.0.6.1)
921
- API Docs can be found here: https://openimageio.readthedocs.io/en/v3.0.6.1/)
@@ -31,7 +43,6 @@
3143
logger.error("Required modules not found. Please install OpenImageIO and numpy.")
3244
raise
3345

34-
3546
have_matplot = False
3647
try:
3748
import matplotlib.pyplot as plt
@@ -66,18 +77,41 @@ def __init__(self):
6677
self._extensions.update(ext.strip() for ext in group.split(","))
6778
logger.debug(f"Cache supported extensions: {self._extensions}")
6879

80+
self.preview = False
81+
self.identifier = "OpenImageIO Custom Image Loader"
82+
6983
def supportedExtensions(self):
7084
"""
71-
Return a set of supported image file extensions.
85+
Derived method to return a set of supported image file extensions.
7286
"""
7387
logger.info(f"OIIO supported extensions: {self._extensions}")
7488
return self._extensions
7589

90+
def set_preview(self, value):
91+
"""
92+
Set whether to preview images when loading and saving
93+
94+
@param value: Boolean indicating whether to enable preview
95+
"""
96+
self.preview = value
97+
98+
def get_identifier(self):
99+
return "OIIO Custom Loader"
100+
76101
def previewImage(self, title, data, width, height, nchannels):
77102
"""
78103
Utility method to preview an image using matplotlib.
79104
Handles normalization and dtype for correct display.
105+
106+
@param title: Title for the preview window
107+
@param data: Image data array
108+
@param width: Image width
109+
@param height: Image height
110+
@param nchannels: Number of image channels
80111
"""
112+
if not self.preview:
113+
return
114+
81115
if have_matplot:
82116
# If the image is float16 (half), convert to float32
83117
if data.dtype == np.float16:
@@ -116,12 +150,9 @@ def previewImage(self, title, data, width, height, nchannels):
116150
def loadImage(self, filePath):
117151
"""
118152
Load an image from the file system (MaterialX interface method).
119-
120-
Args:
121-
filePath (MaterialX.FilePath): Path to the image file
122-
123-
Returns:
124-
MaterialX.ImagePtr: MaterialX Image object or None if loading fails
153+
154+
@param filePath (MaterialX.FilePath): Path to the image file
155+
@returns MaterialX.ImagePtr: MaterialX Image object or None if loading fails
125156
"""
126157
file_path_str = filePath.asString()
127158
logger.info(f"Load using OIIO loader: {file_path_str}")
@@ -316,20 +347,8 @@ def _materialx_type_to_np_type(self, mx_basetype):
316347
mx_render.BaseType.UINT16: np.uint16,
317348
mx_render.BaseType.INT8: np.int8,
318349
mx_render.BaseType.INT16: np.int16,
319-
mx_render.BaseType.HALF: np.float16, # was 'half'
320-
mx_render.BaseType.FLOAT: np.float32, # was 'float' (float64) -> WRONG
321-
}
322-
return type_mapping.get(mx_basetype, None)
323-
324-
def _materialx_type_to_np_type_2(self, mx_basetype):
325-
"""Map MaterialX base type to NumPy dtype."""
326-
type_mapping = {
327-
mx_render.BaseType.UINT8: 'uint8',
328-
mx_render.BaseType.UINT16: 'uint16',
329-
mx_render.BaseType.INT8: 'int8',
330-
mx_render.BaseType.INT16: 'int16',
331-
mx_render.BaseType.HALF: 'half',
332-
mx_render.BaseType.FLOAT: 'float',
350+
mx_render.BaseType.HALF: np.float16,
351+
mx_render.BaseType.FLOAT: np.float32,
333352
}
334353
return type_mapping.get(mx_basetype, None)
335354

@@ -341,6 +360,7 @@ def test_load_save():
341360
parser = argparse.ArgumentParser(description="MaterialX OIIO Image Handler")
342361
parser.add_argument("path", help="Path to the image file")
343362
parser.add_argument("--flip", action="store_true", help="Flip the image vertically")
363+
parser.add_argument("--preview", action="store_true", help="Preview the image before saving")
344364
args = parser.parse_args()
345365

346366
test_image_path = args.path
@@ -350,15 +370,15 @@ def test_load_save():
350370

351371
# Create MaterialX handler with custom OIIO image loader
352372
loader = OiioImageLoader()
373+
loader.set_preview(args.preview)
353374
handler = mx_render.ImageHandler.create(loader)
354-
#manager = mx_render.getPluginManager()
355-
#handler = manager.getImageHandler()
356-
logger.info(f"Created {handler} with loader")
375+
logger.info(f"Created image handler with loader ({loader.get_identifier()}): {handler is not None}")
357376
handler.addLoader(loader)
358377

359378
mx_filepath = mx.FilePath(test_image_path)
360379

361380
# Load image using handler API
381+
logger.info('-'*45)
362382
logger.info(f"Loading image from path: {mx_filepath.asString()}")
363383
mx_image = handler.acquireImage(mx_filepath)
364384
if mx_image:
@@ -374,11 +394,17 @@ def test_load_save():
374394

375395
# Save image using handler API (to a new file)
376396
logger.info('-'*45)
377-
out_path = mx.FilePath("saved_" + os.path.basename(test_image_path))
378-
if handler.saveImage(out_path, mx_image, verticalFlip=args.flip):
379-
logger.info(f"MaterialX Image saved to {out_path.asString()}")
397+
398+
# Retrieve cached image
399+
mx_image = handler.acquireImage(mx_filepath)
400+
if mx_image:
401+
out_path = mx.FilePath("saved_" + os.path.basename(test_image_path))
402+
if handler.saveImage(out_path, mx_image, verticalFlip=args.flip):
403+
logger.info(f"MaterialX Image saved to {out_path.asString()}")
404+
else:
405+
logger.error("Failed to save image.")
380406
else:
381-
logger.error("Failed to save image.")
407+
logger.error("Failed to acquire image for saving.")
382408
else:
383409
logger.error("Failed to load image.")
384410

0 commit comments

Comments
 (0)