Javascript Extended-Range Image
viewer
[1] ... [4]
to toggle between images, [?]
for help
JERI allows displaying EXR images inside a website. The viewer is built on top of OpenEXR and provides a simple user interface for efficient navigation. The EXR files (JPEGs and PNGs are supported too) are specified using a JSON string and loaded on demand, asynchronously and cached for best user experience.
The viewer was designed for quick and intuitive comparisons of many images. It features a multi-level image selector and keyboard bindings for easy navigation through large image sets. Correct the exposure, visualize various error maps, and zoom in excessively to see pixel values in text!
JERI provides a multi-level menu for organizing large sets of images. Once the image is loaded, you can pan, zoom, change exposure ([e]
/ [E]
), or switch to another image using keyboard shortcuts.
For help: [?]
const config = {
title: 'root',
children: [
{
title: 'Glass of water',
children: [
{ title: 'Input image', image: 'glass-input.exr' },
{ title: 'Improved', image: 'glass-denoised.exr' },
{ title: 'Reference', image: 'glass-ref.exr' }
]
},
{
title: 'Living room',
children: [
{ title: 'Input image', image: 'living-room-input.exr' },
{ title: 'Improved', image: 'living-room-denoised.exr' },
{ title: 'Reference', image: 'living-room-ref.exr' }
]
}
]
};
Jeri.renderViewer(document.getElementById('root'), config);
When a reference image is available, JERI can compute false-color error maps between two images. The viewer supports L1, L2 (MSE), MAPE, MRSE, SMAPE and SSIM.
const config = {
title: 'root',
children: [
{ title: 'Improved', image: 'glass.exr' },
{ title: 'Reference', image: 'glass-ref.exr' },
{
title: 'SSIM',
lossMap: {
'function': 'SSIM',
imageA: 'glass.exr',
imageB: 'glass-ref.exr'
}
},
]
};
Jeri.renderViewer(document.getElementById('root'), config);
JERI is written in React and built with Webpack. If this matches your setup, you can simply install JERI with npm install jeri
, and use it like so:
import { ImageViewer } from 'jeri';
import * as ReactDOM from 'react-dom';
function configForImage(imageName) {
return {
title: 'root',
children: [
{ title: 'Image', image: `/img/${imageName}.exr` },
{ title: 'Reference', image: `/img/${imageName}-ref.exr` },
]
};
}
const MyApp = ({ imageName }) => (
<div>
<p>Inspecting {imageName}</p>
<div style={{position: 'relative', height: '300px'}}>
<ImageViewer data={configForImage(imageName)} />
</div>
</div>
);
ReactDOM.render(
<MyApp imageName="glass" />,
document.getElementById('root')
);
By default, JERI comes with multi-image viewing, keyboard shortcuts, etc. If you just need to show a simple EXR image, you can choose to just use JERI's EXR parsing and basic display.
// See Github: build_web/examples/example_basic.html
const cache = new Jeri.ImageCache();
const imgUrl = "./img/glass.exr";
cache.get(imgUrl)
.then((image) => {
// ImageLayer displays an image
const imageLayer = new Jeri.ImageLayer(document.getElementById('image-layer'), image);
// MouseLayer detects and reports mouse and zoom events
const mouseLayer = new Jeri.MouseLayer(document.getElementById('mouse-layer'), image);
mouseLayer.setEnableMouseEvents(true);
// They can be connected as follows:
mouseLayer.onTransformationChange(function (transformation) {
imageLayer.setTransformation(transformation);
});
})
.catch((error) => console.error(error));
JERI contains a version of OpenEXR that was compiled to JavaScript using emscripten. The parsing is done asynchronously in webworker process to prevent blocking the UI.
Everything in JERI can be controlled using a keyboard. To find out about all the shortcuts, select a viewer and press [?]
You can inspect high dynamic range images in JERI by changing exposure settings, panning the image around and zooming in to see all the details.