Last active
January 29, 2020 23:01
-
-
Save oeway/77372e861c09ba4841d8f4a8059af03c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<docs> | |
# SCIFIO.js transpiled with Java2Script | |
Source code: https://github.com/BobHanson/scifio-SwingJS | |
Distribution: https://github.com/oeway/static/tree/master/j2s | |
This library was made during the Dresden Hackathon in Dec. 2019. | |
People who participant into this project: Bob Hanson, Curtis Rueden, Wei Ouyang and Florian Jug | |
</docs> | |
<config lang="json"> | |
{ | |
"name": "SCIFIO-Demo", | |
"type": "window", | |
"tags": [], | |
"ui": "", | |
"version": "0.1.9", | |
"cover": "", | |
"description": "SCIFIO.js transpiled with Java2Script", | |
"icon": "extension", | |
"inputs": null, | |
"outputs": null, | |
"api_version": "0.1.7", | |
"env": "", | |
"permissions": [], | |
"requirements": [ | |
"https://oeway.github.io/static/j2s/swingjs/swingjs2.js", | |
"https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js", | |
"https://static.imjoy.io/spectre.css/spectre.min.css", | |
"https://static.imjoy.io/spectre.css/spectre-exp.min.css", | |
"https://static.imjoy.io/spectre.css/spectre-icons.min.css", | |
"https://unpkg.io/[email protected]/dist/itkVtkViewerCDN.js", | |
"https://unpkg.com/[email protected]/umd/itk.js", | |
"https://unpkg.com/[email protected]/dist/vtk.js" | |
], | |
"dependencies": [], | |
"defaults": {"fullscreen": true} | |
} | |
</config> | |
<script lang="javascript"> | |
// "https://oeway.github.io/static/j2s/swingjs/swingjs2.js", "https://oeway.github.io/static/j2s/swingjs/j2s/core/core_project.z.js", | |
const app = new Vue({ | |
el: '#app', | |
data: { | |
testFiles: [ | |
{name: 'TIF file', path: 'https://oeway.github.io/static/j2s/data/out_benchmark_v1_2018_x64y64z5c2s1t1.ids.tif'}, | |
], | |
axes: [], | |
x_axis: -1, | |
y_axis: -1, | |
ch_axis: -1, | |
z_axis: -1, | |
status: 'Initializing SCIFIO...', | |
img: null, | |
ready: false, | |
selectedFile: 'https://oeway.github.io/static/j2s/data/out_benchmark_v1_2018_x64y64z5c2s1t1.ids.tif' | |
}, | |
methods: { | |
openFileDialog(){ | |
this.$refs['file-input'].click(); | |
}, | |
loadFile(event){ | |
const file =event.target.files[0]; | |
const reader = new FileReader(); | |
reader.onload = async (e)=>{ | |
const arrayBuffer = reader.result; | |
const images = await io.scif.img.ConvertImg.readImage(file.name, new Int8Array(arrayBuffer));//io.scif.img.ConvertImg.testReadImage('x64y64z5c2s1t1.ids.tif', 'https://oeway.github.io/static/j2s/data/out_benchmark_v1_2018_x64y64z5c2s1t1.ids.tif')//io.scif.img.ConvertImg.readImage(name); | |
console.log('image loaded:', images) | |
this.parseImage(images) | |
api.showMessage('Loading image...') | |
this.$forceUpdate(); | |
// await this.renderImage() | |
await this.displayImage() | |
console.log('Here is the image data: ======>', images) | |
api.showMessage('Image file loaded.') | |
} | |
reader.readAsArrayBuffer(file); | |
}, | |
parseImage(images){ | |
const img = images.get$I(0); | |
this.axes = []; | |
for(let i=0;i<img.axisList.size;i++){ | |
const axis = img.axisList.get$I(i); | |
this.axes.push({label: axis.type.label, min: img.min[i], max: img.max[i], selected: 0, index: i}) | |
if(axis.type.label === 'X'){ | |
this.x_axis = i | |
} | |
else if(axis.type.label === 'Y'){ | |
this.y_axis = i | |
} | |
else if(axis.type.label === 'Channel'){ | |
this.ch_axis = i | |
} | |
else if(axis.type.label === 'Z'){ | |
this.z_axis = i | |
} | |
} | |
this.img = img; | |
}, | |
async readTestFile(){ | |
const path = this.selectedFile; | |
api.showMessage(`Loading test image "${path}"...`) | |
const images = await io.scif.img.ConvertImg.readImageFromUrl('x64y64z5c2s1t1.ids.tif', path);//io.scif.img.ConvertImg.testReadImage('x64y64z5c2s1t1.ids.tif', 'https://oeway.github.io/static/j2s/data/out_benchmark_v1_2018_x64y64z5c2s1t1.ids.tif')//io.scif.img.ConvertImg.readImage(name); | |
console.log('image loaded:', images) | |
this.parseImage(images); | |
api.showMessage('Loading image...') | |
this.$forceUpdate(); | |
// await this.renderImage() | |
await this.displayImage() | |
console.log('Here is the image data: ======>', images) | |
api.showMessage('Image file loaded.') | |
}, | |
async renderImage(){ | |
const canvas = this.$refs.image_canvas; | |
canvas.width = this.img.img.dimension[this.x_axis]; | |
canvas.height = this.img.img.dimension[this.y_axis]; | |
var channel_pixels = this.img.img.dimension[this.x_axis] * this.img.img.dimension[this.y_axis]; | |
var ch_size = 1 | |
if(this.ch_axis == -1){ | |
ch_size = this.img.img.dimension[this.ch_axis]; | |
} | |
var image_pixels = channel_pixels * ch_size; | |
var ctx = canvas.getContext('2d'); | |
var myImageData = ctx.getImageData(0, 0, canvas.width, canvas.height); | |
// ctx.fillStyle = 'rgba(30, 100, 100, 255)'; | |
// ctx.fillRect(0, 0, 10, 10); | |
let v; | |
const selected_ch = this.ch_axis==-1? 1: this.axes[this.ch_axis].selected; | |
const selected_z = this.z_axis==-1? 1: this.axes[this.z_axis].selected; | |
const image_offset = selected_ch*channel_pixels + image_pixels * selected_z; | |
console.log('=============>', image_pixels, selected_ch, selected_z, image_offset) | |
for(let i=0;i<canvas.width;i++){ | |
for(let j=0;j<canvas.height;j++){ | |
v = this.img.img.data.data[image_offset + j*canvas.width+i]/255*5; | |
if(v>255) v=255; | |
myImageData.data[(j*canvas.width+i)*4] = v; | |
myImageData.data[(j*canvas.width+i)*4+1] = v; | |
myImageData.data[(j*canvas.width+i)*4+2] = v; | |
myImageData.data[(j*canvas.width+i)*4+3] = 255; | |
} | |
} | |
ctx.putImageData(myImageData, 0, 0); | |
}, | |
async displayImage(){ | |
const size = [this.img.img.dimension[this.x_axis], this.img.img.dimension[this.y_axis], this.img.img.dimension[this.z_axis]] | |
const imgArray = this.img.img.data.data; | |
console.log('=============>', size, imgArray) | |
const container = document.querySelector('#viewer'); | |
const containerStyle = { | |
position: 'relative', | |
width: '100%', | |
height: '600px', | |
minHeight: '400px', | |
minWidth: '400px', | |
margin: '1', | |
padding: '1', | |
top: '0', | |
left: '0', | |
overflow: 'hidden', | |
display: 'block-inline' | |
}; | |
const viewerStyle = { | |
backgroundColor: [1.0, 1.0, 1.0], | |
containerStyle: containerStyle, | |
}; | |
let is3D = true | |
let imageData = vtk.Common.DataModel.vtkITKHelper.convertItkToVtkImage({ | |
imageType: { dimension: 3, pixelType: 1, componentType: 'uint16_t', components: 1}, | |
name: 'test image', | |
origin: [0,0,0], | |
spacing: [1,1,1], | |
direction:{data: [1,0,0,0,1,0,0,0,1]}, | |
size: size, | |
data: imgArray | |
}) | |
is3D = true; | |
this.viewer = await itkVtkViewer.createViewer(container, { | |
viewerStyle: viewerStyle, | |
image: imageData, | |
pointSets: null, | |
geometries: null, | |
use2D: !is3D, | |
rotate: false, | |
}) | |
//const viewProxy = this.viewer.getViewProxy() | |
//const renderWindow = viewProxy.getRenderWindow() | |
// Firefox requires calling .getContext on the canvas, which is | |
// performed by .initialize() | |
//renderWindow.getViews()[0].initialize() | |
// const viewCanvas = renderWindow.getViews()[0].getCanvas() | |
// const stream = viewCanvas.captureStream(30000./1001.) | |
// const renderer = viewProxy.getRenderer() | |
// const viewportPosition = vtkCoordinate.newInstance() | |
// viewportPosition.setCoordinateSystemToNormalizedViewport() | |
} | |
} | |
}) | |
function initScifio(){ | |
return new Promise((resolve, reject)=>{ | |
if (!self.SwingJS)alert('swingjs2.js was not found. It needs to be in swingjs folder in the same directory as ' + document.location.href) | |
const Info = { | |
code: null, | |
main: "io.scif.img.ConvertImg", | |
core: "_project", | |
width: 850, | |
height: 550, | |
readyFunction: null, | |
serverURL: '', | |
j2sPath: 'swingjs/j2s', | |
console: 'sysout', | |
allowjavascript: true | |
} | |
SwingJS.getApplet('scifioApplet', Info) | |
api.log('initialized') | |
window.j2sReadyCallback = ()=>{ | |
api.showMessage('scifio is ready!' ) | |
app.status = 'SCIFIO is ready.' | |
app.ready = true; | |
app.$forceUpdate() | |
// J2S.getFileFromDialog(function(bytes){alert(bytes.length)},"bytes") | |
resolve() | |
} | |
}) | |
} | |
class ImJoyPlugin { | |
async setup() { | |
await initScifio() | |
} | |
async run(ctx) { | |
} | |
} | |
api.export(new ImJoyPlugin()) | |
</script> | |
<window> | |
<div style="padding-left: 10px;" id="app"> | |
<header class="navbar"> | |
<section class="navbar-section"> | |
<a class="navbar-brand text-bold mr-2">SCIFIO.js</a> | |
<!-- <a href="..." class="btn btn-link">Docs</a> | |
<a href="..." class="btn btn-link">GitHub</a> --> | |
<a v-if="ready" class="btn btn-link hide-on-mobile" target="_blank" :href="selectedFile"> Download example file</a> | |
<div class="input-group input-inline"> | |
<button class="btn input-group-btn" @click="readTestFile()" v-if="ready">Load Example File</button> | |
<button v-if="ready" class="btn btn-primary input-group-btn hide-on-mobile" @click="openFileDialog()">Load Local File</button> | |
</div> | |
</section> | |
<section class="navbar-section"> | |
</section> | |
</header> | |
<h4 v-if="!ready">{{status}}</h4> | |
<!-- <div class="form-group" v-if="ready"> | |
<select class="form-select" id="filename" v-model="selectedFile"> | |
<option :value="file.path" v-for="file in testFiles" :key="file.path">{{file.name}}</option> | |
</select> | |
</div> --> | |
<!-- <a v-if="ready" :href="'https://oeway.github.io/static/j2s/'+selectedFile"> Selected file: {{selectedFile}}</a> --> | |
<input ref="file-input" @change="loadFile" type="file" name="name" style="display: none;" /> | |
<!-- <canvas ref="image_canvas" style="width:35%;" width="100" height="100"></canvas> --> | |
<p v-if="!img">Transpiled with Java2Script (by Bob Hanson)</p> | |
<div style="position: relative;"> | |
<div id="viewer"> </div> | |
</div> | |
<template v-for="a in axes" :key="a.label" > | |
<div v-if="a.label!=='X' && a.label!=='Y'"> | |
<br> | |
<span>{{a.label}}</span> | |
<input class="slider" @change="renderImage()" type="range" :min="a.min" :max="a.max" v-model="a.selected"> | |
</div> | |
</template> | |
<div id="sysout"> | |
</div> | |
</div> | |
</window> | |
<style> | |
.icon::before { | |
position: relative; | |
} | |
.navbar .navbar-brand { | |
font-size: 1.5rem; | |
text-decoration: none; | |
} | |
@media all and (max-width: 512px) { /* Change Width Here */ | |
.hide-on-mobile { | |
display: none; | |
} | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment