Loading and Saving Images

Image I/O

Images can be loaded (or saved) either from a RED file or from a common image file format like JPEG, PNG or HDR:

How to Load and Save Image to .red File?

HOOPS Luminate comes with a handful built-in file format called .red. This file format can be used to save any RED resources and is quite quick at reloading time. This format can be used to save images as well in a lossless compressed way:

Save an Image

// image2d is a pointer to a RED image implementing the RED::IImage2D interface.
// red_file is a pointer to a previously created RED file.
// resmgr is a pointer to the RED resource manager.

RED::IREDFile* ifile = red_file->As< RED::IREDFile >();

// Save the image to a RED file.
RED::StreamingPolicy policy;
RC_TEST( ifile->Write( image2d, policy, resmgr ) );

Load an Image

// red_file is a pointer to a previously created RED file.
// image2d is a pointer to a 2D HOOPS Luminate image implementing the RED::IImage2D interface.

// Get a pointer to the RED resource manager.
RED::Object* resmgr = RED::Factory::CreateInstance( CID_REDResourceManager );
RED::IResourceManager* iresmgr = resmgr->As< RED::IResourceManager >();

// Load the RED file.
RED::Vector< unsigned int > ctx;
RED::IREDFile* ifile = red_file->As< RED::IREDFile >();

RED::StreamingPolicy policy;
RED::FileHeader file_header;
RED::FileInfo file_info;
RC_TEST( ifile->Load( "./my_file.red", iresmgr->GetState(), policy, file_header, file_info, ctx ) );

// Admitting there was only one context loaded from the file containig a single image, we can access
// to our image through the RED::IDataManager interface:
RED::IDataManager* idatamgr = iresmgr->GetDataManager()->As< RED::IDataManager >();
RC_TEST( idatamgr->GetImage( image2d, ctx[0], 0 ) )

Contrary to other common image file formats (JPEG or PNG for example), the native image pixel format is preserved, whatever it is.

Note

You can also load or save images to common file formats like JPEG, PNG or HDR (see How to Load and Save Image to File? for more details).

How to Load and Save Image to File?

HOOPS Luminate provides support for some of the most popular image file formats including JPEG, PNG and HDR.

The JPEG is a lossy format which gives very high compression ratio but only save images in RGB format (no alpha). The PNG format is a lossless format with smaller compression ratio than JPEG but with alpha support. Finally the HDR format must be the format of choice to save floating point images (32bit per component) with little lossless compression.

The image I/O methods are located in RED::ImageTools and work as follows:

Save an Image

// image2d is a pointer to a RED image implementing the RED::IImage2D interface.

// Save the image to a JPEG file.
RC_TEST( RED::ImageTools::Save( image2d, false, "./my_image.jpg", true, false, 0.8f ) );

// Save the image to a PNG file.
RC_TEST( RED::ImageTools::Save( image2d, false, "./my_image.png", false, false, 0.8f ) );

Load an Image

// image2d is a pointer to a RED image implementing the RED::IImage2D interface.

// Get a pointer to the RED resource manager.
RED::Object* resmgr = RED::Factory::CreateInstance( CID_REDResourceManager );
RED::IResourceManager* iresmgr = resmgr->As< RED::IResourceManager >();

// Load the image from a HDR file to graphics card memory with target RECT.
RC_TEST( RED::ImageTools::Load( image2d, "./my_image.hdr", RED::FMT_FLOAT_RGB, false, false, RED::TGT_TEX_RECT, iresmgr->GetState() ) );

Note

You can also load or save images to .red files. In that case, the image is compressed with no loss and saved in its native pixel format (see How to Load and Save Image to .red File? for more details).

What differs is that in a RED file, the image is saved with its whole configuration including targets, filtering information. Moreover, in a RED file, an image can be of any HOOPS Luminate supported types (Composite, cube, 3d…) and pixel formats while common image file formats only support 2d images in a reduced set of pixel formats.

Supported Image Formats

The supported common image file formats are:

  • JPG for RGB images

  • PNG for RGB/RGBA images

  • HDR for floating point pixel formats

The JPEG format is known for its very good compression/quality ratio and can be used any time the size of the output image matters. However, due to its specifications, the format doesn’t support pixel formats other than RED::FMT_RGB. Any other pixel format will be converted by the API following the table given in RED::ImageTools::Save.

Note

Do not forget that JPEG is a lossy compression format. Don’t rely on it to preserve all the details of your images.

The PNG format provides lossless compression: image quality is preserved at the price of bigger files. Pixel formats with alpha channels are supported. As for JPEG, input pixels may be converted prior to saving following the conversion rules in RED::ImageTools::Save.

Finally HDR (for High Dynamic Range) is a lossless compressed image format which can handle pixel formats in floating point precision. It lets you save on disk outputs from the HOOPS Luminate ray-tracer (which are high dynamic range images) without loosing quality due to quantification. It also becomes very useful when it comes to load environment photographs which serve as light textures for hemispherical lighting (see http://www.hdrlabs.com for examples of how to use HDR images to lit your 3d scenes).

When to use the Local Storage?

Each HOOPS Luminate image comes with a local storage which can be used to store a local copy of the image content. Because images are synchronously processed in HOOPS Luminate, you can’t get access or modify image contents while a rendering operation is being processed (Modifying Images During a Draw). Hence, if you create images on-the-fly by loading them from a file for example, you must guarantee that all the image operations take place between two rendering calls.

Local storages were introduced to avoid such situations where the rendering is interrupted during an image load or an image edition. It serves as an intermediate location between the image source and the renderer memory where content processing can occur asynchronously from the rendering operations. This enables you to load data in parallel of a rendering operation without needing to interrupt it.

When the source is a RED file, the default storage used is the renderer memory (can be either graphics card or main memory). To change that, you need to set the local images flag in the file policy (RED::StreamingPolicy::SetLocalImages) to true.

When the source is a common image file format, the destination storage needs to be specified in the call (see RED::ImageTools::Load).

Whatever the source you use, contents loaded in local storages are not available to the renderer until they’ve been explicitly uploaded (see Managing Image Pixels in the doc Manipulating Images).

Note

If all your image edition operations occur before the first call to the renderer, you don’t need to worry about the local storage and can send directly the image contents to their default storages.