IOFormat  IOF_v0.34.0_release
Fundamentals

Open an Image

Initialization

IOFormat does not necessarily need to be initialized, but it is a way to force plugins to be loaded at start-up, to avoid some latency during the first opening at runtime.

Retrieve view From a file path

IOFormat provides methods to directly retrieve a view from a path. The filename extension will determine the format, and thus the extractor to instantiate. Theorically, IOFormat can handle any kind of format, so this method cannot directly return an ImageView. You will have to check first the type of view returned, and then transform it.

Concerning images, IOFormat can return three kinds of view:

  • ImageView (Readable at minimum)
  • MultiImageView (Readable at minimum)
  • LodImageView (Readable at minimum)

In case of problem (file not found, format not recognized, decoding issue...), the method will return an empty view.

auto view = ioformat::openView("tmp/image.tiff");
if (ImageViewProvider::isImage(view))
{
auto imgView = ImageViewProvider::toImage(view);
// process image
}
else if (MultiImageViewProvider::isMultiImage(view))
{
auto stackView = MultiImageViewProvider::toMultiImage(view);
// process multi image
}

Important remark: at this moment, image content is not loaded in memory. No copy is done.

Load in memory from a file path

Users can decide to directly load in memory the full content of the loaded image. That way, the view is directly created in memory, through a specific method.

For now, this functionality is only for single-frame images. If given file contains more than one frame, the method will fail (an exception will be raised).

auto image = ioformat::readImage("tmp/image.bmp");

Get a view from an URI

You have the possibility to load a view from an URI. This allows to load an image with a network protocol (HTTP or a file using the prefix file '://').

Remark: In the case of HTTP, the server must support HTTP range requests.

2 methods are available for 2 distinct cases:

  • URI allows to retrieve remote file extension, and thus its supposed format
  • URI does not allow to identify file format. Format must be specified at method call.
Uri uri("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png");
auto view = ioformat::openView(uri);

And the case when file format cannot be identified with its URI. Format must be specified:

// for example, a PHP request can point toward an image, but nothing in the request indicates file format
Uri uri("http://google.com?id=1&name=wayne");
auto view = ioformat::openView(uri, "PNG");

Get a view from any accessor

For any other cases, you can use an accessor as container for your image to decode.

You can have a look onto 'accessor concept' section in IOLink user-guide for more details.

Once you have your content in an accessor, IOFormat provides a method to create a view onto this accessor. On the other hand, you have to know the format of your data.

Remark: IOLink provides a factory to create a view onto an accessor, but with raw data only (not encoded). This one is different, since data are encoded in the accessor, and only IOFormat has capacities to decode them.

// you have an accessor onto an encoded image (whatever it comes from)
std::shared_ptr<DataAccess> accessor = .... ;
// you know your data represent a PNG image
auto view = ioformat::openView(accessor, "PNG");

Open a stack of files

Using a pattern

The StackReader factory can be used to aggregate files which names follow a pattern into an ImageView. Methods from this factory usually take a pattern and the interpretation of the stacking dimension. The pattern format is quite simple: variable parts of the path are indicated with a wildcard "*". The wildcard must only be in the last segment of the pattern. For example some/dir/img_*.png is valid, where some/dir_*/img_*.png is invalid.

  • openImageFromPattern will not load anything in memory, so it is useful for out of core mechanics.
  • readImageFromPattern will stack the files and then load the resulting view in memory for better performance.
std::shared<ImageView> img = ioformat::StackReader::openImageFromPattern("some/dir/img_*.png", ImageDimension::SLICE);

Using a file list

A file list is a file where each line is a path to an image, StackReader::openListFile will open such a file list and create a stacked image using the listed images in order. The StackReader::loadListFile variant do all the same, and then load the stacked image in memory.

Example of an image list:

some/path/to/file.ext
some/other/path/to/file.ext

Code example to load a list file:

std::shared<ImageView> img = ioformat::StackReader::openImageFromListFile("some/dir/stack.lst", ImageDimension::SLICE);

Export to a format

Exporting a view into a specific format is to encode your view content into this format. But each format has its own specificity, limitation, and can request some parameters (compression, color, ...). Each format needs a specific writer.

Generic method

If you need to export your view content into a file or stream, the easiest way is to use the write view method. The appropriate writer plugin will be internally used. Default options of writers will be used for encoding.

This is a simple code example:

auto image = ImageViewFactory::allocate(VectorXu64{64, 64}, DataTypeId::UINT8);
// image is encoded in PNG in the given file (extension of the file path determines the format)
ioformat::writeView(image, "tmp/image.png");
auto outputStream = StreamAccessFactory::openFile("tmp/image.raw");
ioformat::writeView(image, outputStream, "PNG"); // image is encoded in PNG and stored in the given stream
ioformat::writeView(image, outputStream, "MRC"); // image is encoded in MRC and stored in the given stream

Advanced method

You can use advanced API methods to automatically let IOFormat choose for you the appropriate writer according to the desired output format or directly the plugin to use. All these methods return a writer which could then be used for advanced configuration.

Important remark: a writer can only be used for one writing. If you need to write your data a second time, another writer shall be created.

Following methods are provided in IOFormat API:

static std::shared_ptr<iolink::Writer> openWriter(std::shared_ptr<iolink::View> image,
const std::string& pathFile);
static std::shared_ptr<iolink::Writer> openWriter(std::shared_ptr<iolink::View> image,
std::shared_ptr<iolink::StreamAccess> dst,
const std::string& format);
static std::shared_ptr<iolink::Writer> openWriter(std::shared_ptr<iolink::View> image,
std::shared_ptr<iolink::StreamAccess> dst,
const std::string& format,
const std::string& plugin);

Finally, you can use your created writer as following:

auto image = ImageViewFactory::allocate(VectorXu64{64, 64}, DataTypeId::UINT8);
// in this case, we only need to retrieve any writer for a Jpeg compression to export data into a "toto.jpeg" file
auto writer = ioformat::openWriter(image, "tmp/toto.jpeg");
if (writer)
{
// using writers allow you to configure the encoding
writer->setOption("quality", 70); // compression quality is set here
// data are encoded
writer->writeAll();
}
// destroy writer, else it keeps an handle on created file
writer.reset();

With Writer object, you have possibility to set options for writing step. In the previous example, 'quality' of compression can be customized (to replace default value).

Helpers

IOFormat API provides some helpers.

Using formats

Some IOFormat APIs require to provide the format to encode or decode a data through a stream. This format is given as a characters string and should textually match with one of formats supported by internal plugins.

Example: To encode a view into a stream with JPEG format, you have to specify "JPEG" as 'format'.

An helper exists to easily convert an extension (i.e "jpg" or "png") into a format recognized by IOFormat APIs.

Following example shows how to encode your view into a specific extension whose you don't know the format:

auto image = ImageViewFactory::allocate(VectorXu64{64, 64}, DataTypeId::UINT8);
auto outputStream = StreamAccessFactory::openFile("tmp/image.raw")
// you need to know the format associated to this extension
std::string format = ioformat::formatFromExtension("ali"); // if extension is not handled, an exception is raised
// you can now retrieve a writer for this format
auto writer = ioformat::openWriter(image, outputStream, format);

Configuration

Logger

IOFormat can log messages with different level of criticity:

  • LOG_OFF: No logging at all
  • LOG_CRITICAL: Severe errors that cause premature termination
  • LOG_ERR: runtime errors or unexpected conditions
  • LOG_WARNING: Use of deprecated APIs, poor use of API, 'almost' errors, other runtime situations that are undesirable or unexpected, but not necessarily 'wrong'.
  • LOG_INFO: Interesting runtime events (startup/shutdown).
  • LOG_DEBUG: Detailed information on the flow through the system
  • LOG_TRACE: Only for "tracing" the code and trying to find one part of a function specifically

User is free to select the level of messages which he's interested to display at runtime.

By default, IOFormat log level is initialized with IOLink log level. Level can only be specified at initialization by using Logger object, before any other IOFormat API call.

iolink::Logger::init(iolink::LogLevel::LOG_INFO);
ioformat::Logger::init(iolink::LogLevel::LOG_ERR);
auto view = ioformat::openView("car.png");

In this previous example, IOLink log level is set at INFO level, and IOFormat log level is set at ERROR level.

iolink::Logger::init(iolink::LogLevel::LOG_INFO)
auto view = ioformat::openView("car.png");

In this other example, only IOLink log level is set. IOFormat log level is internally initialized to IOLink log level.

auto view = ioformat::openView("car.png");
ioformat::Logger::init(iolink::LogLevel::LOG_INFO);

In this last example, the IOFormat log level is set after an IOFormat API call. This last line has no effect.

ioformat::openWriter
IOFORMAT_API std::shared_ptr< iolink::Writer > openWriter(std::shared_ptr< iolink::View > view, const std::string &pathFile)
ioformat::writeView
IOFORMAT_API void writeView(std::shared_ptr< iolink::View > view, const std::string &pathFile)
ioformat::openView
IOFORMAT_API std::shared_ptr< iolink::View > openView(const std::string &pathFile)
ioformat::formatFromExtension
IOFORMAT_API std::string formatFromExtension(const std::string &extension)
ioformat::init
IOFORMAT_API bool init()
ioformat::Logger::init
static void init(iolink::LogLevel level)
ioformat::readImage
IOFORMAT_API std::shared_ptr< iolink::ImageView > readImage(const std::string &pathFile)
ioformat
Global namespace which contains all methods to encode/decode data from/into different resources (file...
Definition: Error.h:5
ioformat::StackReader::openImageFromListFile
static std::shared_ptr< iolink::ImageView > openImageFromListFile(const std::string &filePath, iolink::ImageDimension newDim)
ioformat::StackReader::openImageFromPattern
static std::shared_ptr< iolink::ImageView > openImageFromPattern(const std::string &pattern, iolink::ImageDimension newDim)