Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It does not work in node.js. Do you consider adapting it ? #246

Closed
marcelfalliere opened this issue Mar 27, 2018 · 6 comments
Closed

It does not work in node.js. Do you consider adapting it ? #246

marcelfalliere opened this issue Mar 27, 2018 · 6 comments
Assignees
Labels
💻 Change: Feature Change that expands the API

Comments

@marcelfalliere
Copy link

Hello.

Using cornerstone in node-js does not work. It seems to be dependent on document (to create element, canvas, ...).

My use case is : to display a list of .dcm image's thumbnails from a rest api. So loading a .dcm file on the client to show only the thumbnail is out of question. That operation : to fetch the thumbnail from a .dcm file, has to be server side. And cornerstone seems to be able to do that. At least with wado-image-loader, to load the "main" image.

Anyway, are you against using cornerstone server side ? Are there limitations ? Are you accepting pull requests ?

// nodejs
const cornerstone = require('cornerstone-core');
// stack
VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2 Uncaught ReferenceError: document is not defined
    at Object.defineProperty.value (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at t (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at Object.defineProperty.value (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at t (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at Object.defineProperty.value (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at t (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at Object.defineProperty.value (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at t (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at Object.defineProperty.value (VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2)
    at VM80 C:\Users\...\node_modules\cornerstone-core\dist\cornerstone.min.js:2

Thanks

@swederik swederik self-assigned this Mar 27, 2018
@swederik swederik added the 💻 Change: Feature Change that expands the API label Mar 27, 2018
@swederik
Copy link
Member

@brunoalvesdefaria is working on something similar. I'll update this as soon as we have more info.

@marcelfalliere
Copy link
Author

So @brunoalvesdefaria what say you ? 🌮

@swederik
Copy link
Member

swederik commented Apr 6, 2018

We have a working node.js cornerstone rendering pipeline but it is very much in a prototype state.

We had to:

  • Use JSDOM for document / window
  • Polyfill XMLHttpRequest (ensure you're using version 2!), Promises, requestAnimationFrame, CustomEvent (ensure the version you use doesn't require document.createEventObject, since JSDom doesn't provide that)
  • Use perf_hooks for the browser performance API
  • Create a global 'navigator' object, since WADO Image Loader check it for hardwareConcurrency
  • Define properties on 'window.HTMLElement.prototype' for JSDOM so that it can return some hardcoded clientWidth / clientHeight values, since JSDOM doesn't actually do any layout
  • Change WADO Image Loader to add a useWebWorkers: false flag. PR is here: Add useWebWorkers flag to decodeConfig cornerstoneWADOImageLoader#186

I don't know how we could alter Cornerstone Core to support server-side rendering more easily. There is one PR which could alleviate the requestAnimationFrame polyfill (#221). We could maybe switch from XMLHttpRequest to the Fetch API, but we'd still need a polyfill for Node, I guess.

Feel free to test it out and let us know what you think. As I've said, it's a prototype and we don't have time to support for it yet.

Hope that helps!

Erik

@marcelfalliere
Copy link
Author

Seems to me this prototype is simply "take cornerstone and run it window-lessly". This approach seems a bit overkill because there are a bunch of stuff we could ditch from the library : the canvas for instance, the whole UI, the interactions ... Also it seems to be using phantomjs, a headless web browser ; is it for the actual generation of pixels ?

Ideally, the rendering pipeline is one function, something like this :

renderImage(inputPath, outputPath)

where inputPath is the file (png, jpg, dicom, ...) and the outputPath is a png that the function will have to generate. The outputPath could be returned to a web client, or any other client for that matter, to be displayed.

My problem with this lib is the part of the actual rendering is tightly coupled with everything else. Hard to read. The goal of this lib is also not clear enough ... is it a viewer ? An image transformer ? For what kind of images ? So many things not clear. Sorry.

I took a look at https://github.com/kesalin/DicomViewer and it seems the rendering part, thought in objective-c, is separated from the rest, in the code.

@swederik
Copy link
Member

The repository I linked to above is still a mess, but the file I linked to does not require PhantomJS, just Node (and a bunch of NPM modules). What you're looking for may be coming (to some degree) in this PR (#261).

This library will take in 'Image' objects and render them to a canvas. You can write Image Loaders to provide whatever types of images you want.

To do what you propose, you could use the storedPixelDataToCanvasImageData type functions. One of them is here: https://github.com/cornerstonejs/cornerstone/blob/e380f7822f82ab319bd185867b50ca835da15ff9/src/internal/storedPixelDataToCanvasImageData.js

Generally they are in the 'internal' folder, because we don't really expect people to be using them. You could take the output RGBA pixel data array and write it to a PNG with something like pngjs.

I'll happily take PRs if you have some proposals for how the library could be reorganized for both server and client-side usage. Server-side rendering has not really been a focus of this library, but I would be happy to see it supported.

@marcelfalliere
Copy link
Author

Indeed, I tried to make DicomViewer and it does not support compressed image. But it works for non compressed image, the code was a not hard to read.

I also came across Papaya and fo-dicom.

I will try integrating cornerstonejs after all, because the rendered canvas is the simpler. And finally, not render the images server side, but instead do them on the client side. Turns out we can do a lot with a <canvas>.

@swederik swederik closed this as completed May 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💻 Change: Feature Change that expands the API
Projects
None yet
Development

No branches or pull requests

2 participants