UNPKG

js-dicom

Version:

this is js-dicom

170 lines (142 loc) 7.33 kB
/** * This module is responsible for drawing a grayscale imageß */ import setToPixelCoordinateSystem from './setToPixelCoordinateSystem'; import storedPixelDataToCanvasImageData from './storedPixelDataToCanvasImageData'; import generateLut from '../generateLut'; import verifyLicense from '../../VerifyUtility/verify'; var grayscaleRenderCanvas = document.createElement('canvas'); var grayscaleRenderCanvasContext; var grayscaleRenderCanvasData; //var lastRenderedImageId; //var lastRenderedViewport = {}; function initializeGrayscaleRenderCanvas(image) { // Resize the canvas grayscaleRenderCanvas.width = image.width; grayscaleRenderCanvas.height = image.height; // NOTE - we need to fill the render canvas with white pixels since we control the luminance // using the alpha channel to improve rendering performance. grayscaleRenderCanvasContext = grayscaleRenderCanvas.getContext('2d'); grayscaleRenderCanvasContext.fillStyle = 'white'; grayscaleRenderCanvasContext.fillRect(0,0, grayscaleRenderCanvas.width, grayscaleRenderCanvas.height); grayscaleRenderCanvasData = grayscaleRenderCanvasContext.getImageData(0,0,image.width, image.height); } function lutMatches(a, b) { // if undefined, they are equal if(!a && !b) { return true; } // if one is undefined, not equal if(!a || !b) { return false; } // check the unique ids return (a.id === b.id) } function getLut(image, viewport, invalidated) { // if we have a cached lut and it has the right values, return it immediately if(image.lut !== undefined && image.lut.windowCenter === viewport.voi.windowCenter && image.lut.windowWidth === viewport.voi.windowWidth && lutMatches(image.lut.modalityLUT, viewport.modalityLUT) && lutMatches(image.lut.voiLUT, viewport.voiLUT) && image.lut.invert === viewport.invert && invalidated !== true) { return image.lut; } // lut is invalid or not present, regenerate it and cache it generateLut(image, viewport.voi.windowWidth, viewport.voi.windowCenter, viewport.invert, viewport.modalityLUT, viewport.voiLUT); image.lut.windowWidth = viewport.voi.windowWidth; image.lut.windowCenter = viewport.voi.windowCenter; image.lut.invert = viewport.invert; image.lut.voiLUT = viewport.voiLUT; image.lut.modalityLUT = viewport.modalityLUT; return image.lut; } // function doesImageNeedToBeRendered(enabledElement, image) // { // if(image.imageId !== lastRenderedImageId || // lastRenderedViewport.windowCenter !== enabledElement.viewport.voi.windowCenter || // lastRenderedViewport.windowWidth !== enabledElement.viewport.voi.windowWidth || // lastRenderedViewport.invert !== enabledElement.viewport.invert || // lastRenderedViewport.rotation !== enabledElement.viewport.rotation || // lastRenderedViewport.hflip !== enabledElement.viewport.hflip || // lastRenderedViewport.vflip !== enabledElement.viewport.vflip || // lastRenderedViewport.modalityLUT !== enabledElement.viewport.modalityLUT || // lastRenderedViewport.voiLUT !== enabledElement.viewport.voiLUT // ) // { // return true; // } // // return false; // } function getRenderCanvas(enabledElement, image, invalidated) { // apply the lut to the stored pixel data onto the render canvas // if(doesImageNeedToBeRendered(enabledElement, image) === false && invalidated !== true) { // return grayscaleRenderCanvas; // } // If our render canvas does not match the size of this image reset it // NOTE: This might be inefficient if we are updating multiple images of different // sizes frequently. if(grayscaleRenderCanvas.width !== image.width || grayscaleRenderCanvas.height != image.height) { initializeGrayscaleRenderCanvas(image); } // get the lut to use var lut = getLut(image, enabledElement.viewport, invalidated); // gray scale image - apply the lut and put the resulting image onto the render canvas storedPixelDataToCanvasImageData(image, lut, grayscaleRenderCanvasData.data); grayscaleRenderCanvasContext.putImageData(grayscaleRenderCanvasData, 0, 0); return grayscaleRenderCanvas; } /** * API function to draw a grayscale image to a given enabledElement * @param enabledElement * @param invalidated - true if pixel data has been invaldiated and cached rendering should not be used */ function renderGrayscaleImage(enabledElement, invalidated) { if(enabledElement === undefined) { throw "drawImage: enabledElement parameter must not be undefined"; } var image = enabledElement.image; if(image === undefined) { throw "drawImage: image must be loaded before it can be drawn"; } // get the canvas context and reset the transform var context = enabledElement.canvas.getContext('2d'); context.setTransform(1, 0, 0, 1, 0, 0); // clear the canvas context.fillStyle = 'black'; context.fillRect(0,0, enabledElement.canvas.width, enabledElement.canvas.height); // turn off image smooth/interpolation if pixelReplication is set in the viewport if(enabledElement.viewport.pixelReplication === true) { context.imageSmoothingEnabled = false; context.mozImageSmoothingEnabled = false; // firefox doesn't support imageSmoothingEnabled yet } else { context.imageSmoothingEnabled = true; context.mozImageSmoothingEnabled = true; } // save the canvas context state and apply the viewport properties context.save(); setToPixelCoordinateSystem(enabledElement, context); var renderCanvas = getRenderCanvas(enabledElement, image, invalidated); // Draw the render canvas half the image size (because we set origin to the middle of the canvas above) context.drawImage(renderCanvas, 0,0, image.width, image.height, 0, 0, image.width, image.height); verifyLicense(context,enabledElement.canvas.width,enabledElement.canvas.height) context.restore(); // lastRenderedImageId = image.imageId; // lastRenderedViewport.windowCenter = enabledElement.viewport.voi.windowCenter; // lastRenderedViewport.windowWidth = enabledElement.viewport.voi.windowWidth; // lastRenderedViewport.invert = enabledElement.viewport.invert; // lastRenderedViewport.rotation = enabledElement.viewport.rotation; // lastRenderedViewport.hflip = enabledElement.viewport.hflip; // lastRenderedViewport.vflip = enabledElement.viewport.vflip; // lastRenderedViewport.modalityLUT = enabledElement.viewport.modalityLUT; // lastRenderedViewport.voiLUT = enabledElement.viewport.voiLUT; } // Module exports export default renderGrayscaleImage;