Getting started

The easiest way to get started with the JERI viewer is to download the source code as well as the binary package of the latest release.

Viewing examples

To view the examples, you first need to build the source using npm run build. Alternatively you can simply copy all precompiled scripts from the build_web directory in the binary package to the same directory in the source code package.

Because of the cross-origin resource-sharing policy of modern browsers, JERI can only load EXR images when hosted using a web server. A page containing JERI does not work properly when opened using the file:// protocol.

To start a local web server, run one of the following commands from the build_web directory in the source code.


python -m SimpleHTTPServer 8000; # Python 2
python3 -m http.server 8000; # Python 3
npm install -g serve && serve -s . -p 8000 # JavaScript

You can then view the examples at http://localhost:8000/examples. Check the JavaScript console in the viewer for errors.

Embedding JERI

Load the jeri library and its dependency React:


<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.js"></script>
<script src="jeri.js"></script>

Next, describe the hierarchical menu structure of the viewer, like this:


const data = {
  title: 'root',
  children: [
    {
      title: 'Living room',
      children: [ // Arbitrary tree-structured nesting of tabs
        {
          title: 'Denoised',
          image: 'images/test_image.exr',
        },
        {
          title: 'Input',
          image: 'images/test_input.exr',
        },
        {
          title: 'Reference',
          image: 'images/test_reference.exr',
        },
        {
          title: '1-SSIM',
          lossMap: { // JERI can automatically compute false-color error-maps for SSIM, L1, MSE, rMSE, SMAPE
            function: 'SSIM',
            imageA: 'images/test_image.exr',
            imageB: 'images/test_reference.exr',
          }
          tonemapGroup: 'other', // A non-default `tonemapGroup` decouples exposure control from images in other groups.
        },
        {
          title: 'L1',
          tonemapGroup: 'other',
          lossMap: {
            function: 'L1',
            imageA: 'images/test_image.exr',
            imageB: 'images/test_reference.exr',
          }
        },
        {
          title: 'MrSE',
          tonemapGroup: 'other',
          lossMap: {
            function: 'MRSE',
            imageA: 'images/test_image.exr',
            imageB: 'images/test_reference.exr',
          }
        },
      ]
    },
    {
      title: 'Mountains',
      image: 'images/test_image.jpg',
    },
  ]
};

To render the viewer, create a container element and call JERI:


<div id="my-viewer" style="width: 100%; height: 600px;"></div>
<script>
  const data = ...;
  // Call renderViewer as often as you want, any time the data changes
  // Updates are cheap, efficient, and state is preserved
  Jeri.renderViewer(document.getElementById('my-viewer'), data);
</script>

Webworker scripts

JERI parses EXR files using a version of OpenEXR compiled with emscripten. The parsing happens asynchronously using webworkers. For this reason, jeri.js will look for three files:


exr.worker.js # the webworker
exr-wrap.js # a compiled OpenEXR library
exr-wrap.js.mem # an emscripten memory file for the compiled OpenEXR library

By default, these files are expected to be served from the root of the web server (/exr.worker.js etc.) If the files are served from another path, you need to change base url in two scripts:


// jeri.js
__webpack_require__.p = "/";
// exr.worker.js
__webpack_require__.p = "/";

Building and NPM

To customize JERI to fit your own application or to contribute to its development, follow the README on Github. It contains instructions on building JERI yourself. This requires NPM and is based on Webpack.

If you are using JERI in a React app built with Webpack, the documentation on Github also outlines how to install JERI through NPM.