Wei OUYANG
Emma Lundberg Group @ KTH Royal Institute of Technology
- ImageJ compiled into Javascript (with CheerpJ)
- Running in web browser, support tablets & mobile phones
- Share macro via URL (example by J. Mutterer)
- Easy integration with website/apps
A basic ImageJ macro for segmentation:
- Support ITK/VTK viewer and NGFF
- Running DeepImageJ models with Tensorflow.js
- Loading NGFF/Zarr images as virtual stack
Start ImageJ.JS
https://ij.imjoy.io/?open=https://s3.embassy.ebi.ac.uk/idr/zarr/v0.1/6001240.zarr
- Chrome extension by Jérôme Mutterer
- Integrated with OpenFlexure/UC2 microscope software
- WIP: Integrate with OMERO (by Will Moore) WIP: Bioimage Archive
Load HPA Cell Atlas image virtual stack (800GB)
Follow us on Twitter @ImJoyTeam
async function startImageJ(){
const ij = await api.createWindow({src:"https://ij.imjoy.io", name:"ImageJ.JS"})
await ij.runMacro(`run("Fly Brain");`);
await api.getPlugin({src: "https://gist.github.com/oeway/e5c980fbf6582f25fde795262a7e33ec"});
}
async function initializeMacroEditor(editor_container, code){
const editorElm = document.getElementById(editor_container);
if(!editorElm) throw new Error("editor container not found: " + editor_container)
editorElm.style.width = '90%';
editorElm.style.display = 'inline-block';
editorElm.style.height = 'calc(100vh - 300px)';
// force update the slide
Reveal.layout();
let editorWindow;
const config = {lang: 'javascript'}
config.templates = [
{
name: "New",
url: null,
lang: 'javascript',
},
{
name: "Sphere",
url: "https://wsr.imagej.net/download/Examples/Macro/Sphere.ijm",
lang: 'javascript',
},
{
name: "OpenDialog Demo",
url: "https://wsr.imagej.net/download/Examples/Macro/OpenDialog_Demo.ijm",
lang: 'javascript',
},
{
name: "Overlay",
url: "https://wsr.imagej.net/download/Examples/Macro/Overlay.ijm",
lang: 'javascript',
}
]
config.ui_elements = {
run: {
_rintf: true,
type: 'button',
label: "Run",
icon: "play",
visible: true,
shortcut: 'Shift-Enter',
async callback(content) {
try {
let ij = await api.getWindow("ImageJ.JS-" + editor_container)
if(!ij){
//put the editor side by side
editorElm.style.width = '38.2%';
const ijElm = document.createElement('div');
ijElm.id = 'imagej-' + editor_container
ijElm.style.display = 'inline-block';
ijElm.style.width = '61.8%';
ijElm.style.height = editorElm.style.height;
editorElm.parentNode.insertBefore(ijElm, editorElm.nextSibling);
ij = await api.createWindow({src:"https://ij.imjoy.io", name:"ImageJ.JS-" + editor_container, window_id: 'imagej-' + editor_container})
}
await ij.runMacro(content)
} catch (e) {
api.showMessage("Failed to run macro, error: " + e.toString());
} finally {
editorWindow.updateUIElement('stop', {
visible: false
})
editorWindow.setLoader(false);
api.showProgress(100);
}
}
},
}
editorWindow = await api.createWindow({
src: 'https://if.imjoy.io',
name: 'ImageJ Script Editor',
config,
window_id: editor_container,
data: {code}
})
}
Reveal.addEventListener('ij-macro-1', async ()=>{
const code = `run("Blobs (25K)");
setAutoThreshold("Default");
setOption("BlackBackground", true);
run("Convert to Mask");
run("Analyze Particles...", "size=5-Infinity add");
`
initializeMacroEditor('macro-editor-1', code)
})
Reveal.addEventListener('ij-macro-2', async ()=>{
const response = await fetch("https://wsr.imagej.net/download/Examples/Macro/Colors_of_2021.ijm")
const code = await response.text()
initializeMacroEditor('macro-editor-2', code)
})