Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

cornerstone-core

cornerstonejs38.4kMIT2.6.1TypeScript support: definitely-typed

HTML5 Medical Image Viewer Component

DICOM, medical, imaging

readme

cornerstone-core

Cornerstone.js delivers a complete web based medical imaging platform. This repository contains the Cornerstone.js "Core" component which is a lightweight JavaScript library for displaying medical images in modern web browsers that support the HTML5 canvas element.

Read The Docs | Edit the docs


Coverage Status All Contributors

NPM version NPM downloads MIT License

Cornerstone Core is not meant to be a complete application itself, but instead a component that can be used as part of larger more complex applications. See the OHIF Viewer for an example of using the various Cornerstone libraries to build a simple study viewer.

Cornerstone Core is agnostic to the actual container used to store image pixels as well as the transport mechanism used to get the image data. In fact, Cornerstone Core itself has no ability to read/parse or load images and instead depends on one or more ImageLoaders to function.

The goal here is to avoid constraining developers to work within a single container and transport (e.g. DICOM) since images are stored in a variety of formats (including proprietary). By providing flexibility with respect to the container and transport, the highest performance image display may be obtained as no conversion to an alternate container or transport is required. It is hoped that developers feel empowered to load images from any type of image container using any kind of transport. See the CornerstoneWADOImageLoader project for an example of a DICOM WADO based Image Loader.

Cornerstone Core is agnostic to the exact interaction paradigm being used. It does not include any mouse, touch or keyboard bindings to manipulate the various image properties such as scale, translation or ww/wc. The goal here is to avoid constraining developers using this library to fit into a given ui paradigm. It is hoped that developers are empowered to create new paradigms possibly using new input mechanisms to interact with medical images (e.g. Kinect or Accelerometer). Cornerstone does provide a set of API's allowing manipulation of the image properties via javascript. See the CornerstoneTools library for an example of common tools built on top of Cornerstone.

Community

Have questions? Try posting on our google groups forum.

Live Examples

The best way to see the power of this library is to actually see it in use.

Click here for a list of examples of using the Cornerstone library.

Install

Get a packaged source file:

Or install via NPM:

Latest stable release:

npm install cornerstone-core

Pre-release, unstable, mostly for contributors:

npm install cornerstone-core@next

Key Features

  • HTML5/Javascript based library to easily add interactive medical images to web applications
  • Serves as a foundation to build more complex medical imaging applications from - enterprise viewer, report viewer, etc.
  • Supports all HTML5 based browsers including mobile, tablet and desktop
  • Displays all common medical image formats (e.g. 8 bit grayscale, 16 bit grayscale, RGB color)
  • High performance image display
  • Retrieval of images from different systems with different protocols via Image Loader plugin design
  • API support for changing viewport properties (e.g. ww/wc, zoom, pan, invert)

Links

Development Process

Installation

Developer Guide

View the wiki for documentation on the concepts and APIs

View Roadmap

View Backlog

2014 comp.protocols.dicom thread that started this project

CornerstoneTools - A library of common tools that can be used with Cornerstone

CornerstoneWADOImageLoader - A Cornerstone Image Loader that works with WADO-URI, WADO-RS and DICOM P10 files

CornerstoneWebImageLoader - A Cornerstone Image Loader that works with PNG and JPEG files

dicomParser - A JavaScript library designed to parse DICOM for web browsers

Code Contributors

I welcome pull requests, please see FAQ below for guidance on this.

  • @simonmd - CSS improvements in the cornerstoneDemo application
  • @doncharkowsky - The angle tool in cornerstoneTools
  • @prasath-rasterimages - Touch event bindings in cornerstoneTools
  • @jpamburn - Performance optimizations for signed data, fixes for image caching
  • @jmhmd - for getPixels() implementation
  • @devishree-raster - for flip and rotate implementation

FAQ

Why did you decide to license this library using the open source MIT license?

The main reason this library is released as open source is that I believe that medical imaging in particular can do a lot more to improve patient outcomes but the cost of doing so is prohibitive. Making this library open source removes the cost barrier and will hopefully usher in a new set of medical imaging based applications.

The old adage a picture is worth a thousand words is very true in medical imaging. When a patient is going through a disease process, they often face fear and confusion. Medical terminology amplifies these issues as it is hard to understand and therefore disempowering. Medical imaging allows a mysterious health issue to be visualized and therefore brings a level of understanding that just can't be accomplished via textual information found in lab or radiology reports. By helping a patient (and its supporting friends/family) connect with the disease visually through images, it is believed that fear, anxiety and confusion will all be reduced which will increase optimism and therefore patient outcomes.

It is my hope that this library be used to build a variety of applications and experiences to deliver on this vision. The MIT license allows this library to be used in any type of application - personal, open source and commercial and is therefore appropriate to support this vision. If you are reading this, I hope you can join me in this mission as there is still a lot to be done.

Why doesn't Cornerstone natively support the display of DICOM images?

While DICOM has support for just about every type of medical image, there are many cases where medical images are not stored in DICOM format. In many cases, a PACS may receive DICOM images but store them in a proprietary format on disk. In this case, it can be faster to access images by having an image loader that works with a proprietary PACS interface that would not require conversion from the proprietary format into a standard format like DICOM. Another example of this is is dermatology where images are often taken using standard digital cameras and are stored as JPEG not DICOM.

The main reason this library is not based around DICOM is that it wants to reach the widest possible adoption and that will be accomplished by supporting as many types of image containers and transports possible. Another side effect of this approach is that the code base is smaller and easier to understand since it is focused on doing exactly one thing. That being said, it is is expected that the majority of images displayed using this library will have originated as DICOM images. It is therefore important to make sure that there are no limitations with respect to displaying the different types of DICOM images and have robust supporting libraries for DICOM. Separate libraries to add DICOM specific support already exist, check out the CornerstoneWADOImageLoader library and the dicomParser library.

Why doesn't Cornerstone include basic tools like ww/wc using the mouse?

There is no standard for user interaction in medical imaging and a wide variety of interaction paradigms exist. For example, one medical imaging application may use the left mouse button to adjust ww/wc and another may use the right mouse button. The main reason this library does not include tools is that it wants to reach the widest possible adoption and that will only be accomplished by making any interaction paradigm possible. No tools are therefore provided with this library allowing users of the library to choose whatever interaction paradigm they like. It is also hoped that this approach will make it easier for developers to experiment with new user input mechanisms like Kinect or Accelerometer. Another side effect of this approach is that the code base is smaller and easier to understand since it is focused on doing exactly one thing. Tools are provided using the separate CornerstoneTools if desired.

Why doesn't this library support older browsers like IE8?

Much of the performance in this library is possible due to utilizing modern web features such as HTML5 canvas, high performance javascript engines and WebGL. These feature are not avaialble in IE8 and there are no suitable polyfills available. Sorry, upgrade your browser.

Why doesn't this library support stacks of images?

Images stack functionality such as a CT series or MRI series can actually be quite complex. Regardless of what stack functionality is desired, all stacks ultimately need to be able to display a single image and that is what this library is focused on doing. Stack functionality is therefore pushed up to a higher layer. The CornerstoneTools contains stack functionality and is a good place to look to see how various stack related functionality is implemented.

How do you envision this library supporting 3D functionality such as MPR, MIP and VR?

This library would be responsible for displaying the rendered image to the user. The rendering of the 3D image would be done by some other library - perhaps on the server side. This library is purely 2D and has no knowledge of 3D image space. It will probably make sense to have several layers on top of this library to provide 3D functionality. For example, one layer that has a 3D viewport with properties such as transformation matrix, slice thickness, transfer function/LUT, segmentation masks, etc. And another 3D tools layer that provides various tools on top of the 3d viewport (rotate, zoom, segment, scroll, etc).

OHIF/Cornerstone is working with the 3DSlicer project to integrate the two. I also expect to implement client side MPR at some point as the browsers seem to be handling large memory much better.

I would like to contribute code - how do I do this?

Fork the repository, make your change and submit a pull request.

Any guidance on submitting changes?

While I do appreciate code contributions, I will not merge it unless it meets the following criteria:

  • Functionality is appropriate for the repository. Consider posting on the forum if you are not sure
  • Code quality is acceptable. I don't have coding standards defined, but make sure it passes ESLint and looks like the rest of the code in the repository.
  • Quality of design is acceptable. This is a bit subjective so you should consider posting on the forum for specific guidance

I will provide feedback on your pull request if it fails to meet any of the above.

Please consider separate pull requests for each feature as big pull requests are very time consuming to understand. It is highly probably that I will reject a large pull request due to the time it would take to comprehend.

Will you add feature XYZ for me?

If it is in the roadmap, I intend to implement it some day - probably when I actually need it. If you really need something now and are willing to pay for it, try posting on the cornerstone platform google group

Research notice ~~~

Please note that this repository is participating in a study into sustainability of open source projects. Data will be gathered about this repository for approximately the next 12 months, starting from June 2021.

Data collected will include number of contributors, number of PRs, time taken to close/merge these PRs, and issues closed.

For more information, please visit the informational page <https://sustainable-open-science-and-software.github.io/>_ or download the `participant information sheet <https://sustainable-open-science-and-software.github.io/assets/PISsustainable_software.pdf>`__.

Copyright

Copyright 2017 Chris Hafey chafey@gmail.com

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

[2.3.0] - 2019-07-03

Added

  • Added setDefaultViewport() as an exposed internal API method

[2.2.8] - 2018-12-05

Added

  • Added default export named 'cornerstone' to the module

[2.2.7] - 2018-10-25

Changed

  • Deprecate enabledElement.options.colormap option
  • Fix rowPixelSpacing and columnPixelSpacing not to be null (default to 1)
  • jsdocs changes

[2.2.6] - 2018-09-24

Added

  • Broadcast ELEMENT_DISABLED event when disabling a new element on the events object

Changed

  • Broadcast ELEMENT_ENABLED event off events object instead of per element

[2.2.5] - 2018-09-24

Added

  • Broadcast ELEMENT_ENABLED event when enabling a new element
  • enabledElements now have an associated unique id (enabledElement.uuid)

[2.2.4] - 2018-05-04

Removed

  • Removed old fix for clearing the canvas after swaping between 2 colorSpaces (issue #151)

[2.2.3] - 2018-05-02

Fixed

  • Fixed multiple images with different colorSpaces not being rendered correctly (issue #151)
  • Fixed memory leak in drawCompositeImage.syncedViewports (issue #179)
  • Fixed all the build warnings in the test folder

Added

  • Added unit tests for displayed area feature
  • Added 'renderToCanvas' to allow user to directly draw an image to an existent canvas

[2.2.2] - 2018-04-23

Added

  • Added "dist" folder to published package.

[2.2.1] - 2018-04-23

Fixed

  • Fixed viewport scale is NaN when row/col pixel spacing is not present (Issue #262).

[2.2.0] - 2018-04-11

Added

  • Added and exported EVENTS constants for all cornerstone events (thanks @medihack)
  • Added example for integration with React to the docs https://docs.cornerstonejs.org/integration.html
  • Added compute VOI window width/center if not present (thanks @adreyfus)
  • Added Displayed Area in Viewport to support IHE Consistent Presentation of Images (thanks @jdnarvaez)
  • Added HTML example "displayedArea" with the IHE test cases for Consistent Presentation of Images

Fixed

  • Fixed WebGL Rendering to properly determine the datatype (e.g. color, int8, int16...) of the image pixel data
  • Fixed fitToWindow and default viewport for images with different row/col pixel spacing (thanks @luyixin)

Changed

  • Updated project to Webpack4
  • Updated the HTML example "modalityANDVIOLut" to show 1) Reset VOI LUT (forceAuto) and 2) Select a VOI from defined presets (W/L values or and VOI LUT function)
  • Updated the HTML example "resize" to allow setting irregular image sizes (Row and Column pixel spacing) when applying fitting the image to window and zoom in/out

Removed

  • Removed "dist" folder from source

[2.1.0] - 2018-03-02

Added

  • Added Gitbook and documentationjs for API docs
  • Added new tests
  • Added API to support setting the initial viewport for an image without displaying it (thanks @ClaireTagoe)
  • Added support for event handler namespaces

Fixed

  • Fixed scrollbar issues by making the canvas a block element (thanks @medihack)
  • Fixed image caching issues
  • Fixed certain front-end framework (e.g. React) issues by avoiding manipulating the DOM when enabling an element
  • Fixed scaling issue when resizing (thanks @medihack)

[2.0.0] - 2017-12-08

Changed

  • Breaking Change!!! Removed jQuery events from triggerEvent, lower-cased all the event names. e.g. "CornerstoneWebGLTextureRemoved" is now "cornerstonewebgltextureremoved". Only native CustomEvents are now triggered by Cornerstone Core.
  • Breaking Change!!! Image Loaders should now return an Object containing a promise and a function which can cancel the request. The format is { promise, cancelFn }. Migration guide to come...
  • Breaking Change!!! Image cache now stores ImageLoadObjects as described above.

Removed

  • Removed 'commonjs2' parameter from webpack output.library options because it was complaining.
  • Removed 'externals' since we no longer use jQuery
  • Breaking Change!!! putImagePromise, getImagePromise have been removed and replaced with putImageLoadObject, getImageLoadObject

[1.1.4] - 2017-12-08

Added

  • Added the ESLint plugin 'eslint-plugin-import' to keep us from forgetting .js on our imports. The file extension is required when using native ES6 modules in the browser.
  • Added generateColorLut, which is basically the same as generateLut, but only applies VOI LUT transformation, and not the Modality LUT. This is intended to address the display issues reported in https://github.com/cornerstonejs/cornerstoneWADOImageLoader/issues/143

Changed

  • Moved the repository from Chris Hafey's (@chafey) personal page to a new Organization (@cornerstonejs). Renamed all the relevant links. Join us at @cornerstonejs to start contributing!
  • Switched renderColorImage to use the newly created generateColorLUT, so that modality LUT transformations are no longer (incorrectly) applied to color images.

[1.1.3] - 2017-11-17

Added

  • Exporting of triggerEvent function, mainly for use by image loader libraries

Changed

  • Switched rescaleImage to use image columnPixelSpacing instead of relying on metadataProvider (thanks @adreyfus)
  • Switched this changelog to try to follow http://keepachangelog.com/en/1.0.0/

Version 1.1.2

  • Changed the CustomEvent polyfill check to use typeof. It was not working on IE.

Version 1.1.1

  • Added the CustomEvent polyfill for browsers which doesn't support it.
  • Fixed lint issues that were being displayed during tests.

Version 1.1.0

  • Major changes:

In 1.1.0 we have added several rendering functions to support the use of layers for composite images.

Previously, users had to use convertToFalseColorImage which converted the entire grayscale image to a color image, and then rendered the RGB pixels. Now, you can set the 'colormap' property on the viewport and the image will be displayed in false color. The False Color Mapping and Composite Images examples have been updated accordingly.

  • renderLabelMapImage: In medical imaging it is very common to have results stored as label maps. Pixel values are set to arbitrary numbers which represent something specific in an image (e.g. 1 for heart, 2 for lung). These label maps do not require any modality LUT or VOI LUT transformations and can just be mapped to RGBA pixels through color lookup tables. Support for label maps has now (finally!) been added to Cornerstone. Just set the viewport property 'labelmap' to true and add a colormap and you can display a label map.

  • renderGrayscaleImage: Now has support for rendering using either just the alpha channel or RGBA channels. This is required for proper layer support.

  • Removed redundant code in renderWebImage which was being run before renderColorImage was being called. This should hopefully fix performance issues for Web images that have been reported (#164).
  • More work towards dropping jQuery from @maistho: Trigger all jQuery events inside triggerEvent function (#185)
  • Minor code cleanup, converted LookupTable to use ES6 Class syntax

Version 1.0.1

  • Switch package.json 'main' to minified version to reduce bundle sizes
  • jQuery removed from tests (thanks @maistho)

Version 1.0.0

  • Updated to 1.0.0 because 0.13.1 introduced a breaking change with jQuery injection. This doesn't break usage if you are using HTML script tags, but if you are using Cornerstone in a module system, Cornerstone may not properly find jQuery.

The solution for this is to inject your jQuery instance into Cornerstone as follows:

cornerstone.external.$ = $;

An example commit doing this in the OHIF Viewer Meteor application is here: https://github.com/OHIF/Viewers/commit/012bba44806d0fb9bb60af329c4875e7f6b751e0#diff-d9ccd906dfc48b4589d720766fe14715R25

We apologize for any headaches that the breaking change 0.13.1 may have caused for those using module systems.

Version 0.13.2 (deprecated due to breaking change)

  • Added native CustomEvents that are triggered parallel to the jQuery events. This is part of a transition to drop the jQuery dependency entirely.
  • Added the EventTarget interface to cornerstone.events. You can now use cornerstone.events.addEventListener to listen to events. The parallel events have the same names as the current events, but are all lower case.

e.g. CornerstoneImageRendered has a native CustomEvent name 'cornerstoneimagerendered'

Version 0.13.1 (deprecated due to breaking change)

  • Updated dependencies
  • Added JQuery as an injection dependency
  • Properly reexport reference to isWebGLInitialized from WebGL module

Version 0.13.0

  • Removed the all always from imageCache's method decache to better stability
  • Stop putImagePromise() if the image has been purged before being loaded
  • Changed Webpack building file to output files as cornerstone-core for commonjs, commonjs2 and amd
  • Add jquery names for commonjs, commonjs2 and amd
  • Updated to Webpack 3
  • Bug fixes for drawing composite images
  • Bug fix for missing intercept value after false color mapping
  • Math.floor instead of Math.round, to have correct values when v < Range[0] or v > Range[1] for linearIndexLookupMain
  • Avoid setting canva's size with the same value, because it flashes the canvas with IE and Edge
  • Remove parseInt to convert the values of pixelData
  • Updated generateLut to generateLutNew
  • drawCompositeImage synchronizes viewport.hflip
  • Also synchronize vflip
  • Trigger CornerstoneImageCacheMaximumSizeChanged and CornerstoneImageCacheChanged events when changing conerstone image cache
  • Force cornerstone to generate a new LUT and use the color renderer after applying false color mapping

Version 0.12.2

  • Fix VOILUT rendering for Agfa images (issue #106)

Version 0.12.1

  • Fix NPM dependencies, added this changelog
  • Fix viewport sync in composite image example

Version 0.12.0

  • Add layer API support for drawing composite images
  • Remove globals from eslintrc.js
  • Fix broken event firing for WebGL texture cache

Version 0.11.1

  • Add a 'CornerstonePreRender' event that is fire before the image is rendered
  • Switch module imports to include '.js' extensions to improve support for Chrome native modules

Version 0.11.0

  • Switch events to fire on cornerstone.events instead of cornerstone. This was broken when Cornerstone was loaded as a module. Note: If you are currently using $(cornerstone).on(...) to monitor image load progress or cache changes, you need to change this to $(cornerstone.events).on(...)

  • Add previous image information in CornerstoneNewImage event

  • Fix build issues on Windows
  • Fix missing devDependency for Istanbul in package.json
  • Add a number of unit tests, ESLint fixes, and JSDoc comments

Version 0.10.10

  • Fix issues with package.json and Webpack configuration

Version 0.10.9

  • Migrate to new build process with Webpack and Babel. Remove grunt.
  • Migrate to ES6 modules (@brunoalvesdefaria, @zachasme, @lscoder, @jpambrun, @jasonklotzer)
  • Fix issue #115: Grayscale not inverting properly
  • Fix typo in Date.now for performance timing fallback when window.performance is not available

Version 0.10.8

  • Performance improvements for LUT generation (@jpambrun)

Version 0.10.7

  • Revert fix for #101 since it's reducing performance