UNPKG

js-dicom

Version:

this is js-dicom

140 lines (117 loc) 5.95 kB
import $ from 'jquery'; import getImageFrame from './getImageFrame'; import decodeImageFrame from './decodeImageFrame'; import isJPEGBaseline8BitColor from './isJPEGBaseline8BitColor'; import convertColorSpace from './convertColorSpace'; import metaData from './metaData'; import {default as isColorImageFn} from './isColorImage'; import getMinMax from './getMinMax'; import rendering from './rendering'; function isModalityLUTForDisplay (sopClassUid) { // special case for XA and XRF // https://groups.google.com/forum/#!searchin/comp.protocols.dicom/Modality$20LUT$20XA/comp.protocols.dicom/UBxhOZ2anJ0/D0R_QP8V2wIJ return sopClassUid !== '1.2.840.10008.5.1.4.1.1.12.1' && // XA sopClassUid !== '1.2.840.10008.5.1.4.1.1.12.2.1'; // XRF } function setPixelDataType (imageFrame) { if (imageFrame.bitsAllocated === 16) { if (imageFrame.pixelRepresentation === 0) { imageFrame.pixelData = new Uint16Array(imageFrame.pixelData); } else { imageFrame.pixelData = new Int16Array(imageFrame.pixelData); } } else { imageFrame.pixelData = new Uint8Array(imageFrame.pixelData); } } function createImage (dataSet, pixelData, transferSyntax, options) { const canvas = document.createElement('canvas'); const imageFrame = decodeImageFrame(getImageFrame(dataSet), transferSyntax, pixelData, canvas, options); // var imagePixelModule = metaDataProvider('imagePixelModule', imageId); const imagePlaneModule = metaData.metaDataProvider('imagePlaneModule', dataSet); const voiLutModule = metaData.metaDataProvider('voiLutModule', dataSet); const modalityLutModule = metaData.metaDataProvider('modalityLutModule', dataSet); const sopCommonModule = metaData.metaDataProvider('sopCommonModule', dataSet); const isColorImage = isColorImageFn(imageFrame.photometricInterpretation); // JPEGBaseline (8 bits) is a lready returning the pixel data in the right format (rgba) // because it's using a canvas to load and decode images. if (!isJPEGBaseline8BitColor(imageFrame, transferSyntax)) { setPixelDataType(imageFrame); // convert color space if (isColorImage) { // setup the canvas context canvas.height = imageFrame.rows; canvas.width = imageFrame.columns; const context = canvas.getContext('2d'); const imageData = context.createImageData(imageFrame.columns, imageFrame.rows); convertColorSpace(imageFrame, imageData); imageFrame.imageData = imageData; imageFrame.pixelData = imageData.data; } } const image = { color: isColorImage, columnPixelSpacing: imagePlaneModule.pixelSpacing ? imagePlaneModule.pixelSpacing[1] : undefined, columns: imageFrame.columns, height: imageFrame.rows, intercept: modalityLutModule.rescaleIntercept ? modalityLutModule.rescaleIntercept : 0, invert: imageFrame.photometricInterpretation === 'MONOCHROME1', minPixelValue: imageFrame.smallestPixelValue, maxPixelValue: imageFrame.largestPixelValue, render: undefined, // set below rowPixelSpacing: imagePlaneModule.pixelSpacing ? imagePlaneModule.pixelSpacing[0] : undefined, rows: imageFrame.rows, sizeInBytes: imageFrame.pixelData.length, slope: modalityLutModule.rescaleSlope ? modalityLutModule.rescaleSlope : 1, width: imageFrame.columns, windowCenter: voiLutModule.windowCenter ? voiLutModule.windowCenter[0] : undefined, windowWidth: voiLutModule.windowWidth ? voiLutModule.windowWidth[0] : undefined, decodeTimeInMS: imageFrame.decodeTimeInMS }; // add function to return pixel data image.getPixelData = () => imageFrame.pixelData; // Setup the renderer if (image.color) { image.render = rendering.renderColorImage; image.getCanvas = function () { canvas.height = image.rows; canvas.width = image.columns; const context = canvas.getContext('2d'); context.putImageData(imageFrame.imageData, 0, 0); return canvas; }; } else { image.render = rendering.renderGrayscaleImage; } // calculate min/max if not supplied if (image.minPixelValue === undefined || image.maxPixelValue === undefined) { const minMax = getMinMax(imageFrame.pixelData); image.minPixelValue = minMax.min; image.maxPixelValue = minMax.max; } // Modality LUT if (modalityLutModule.modalityLUTSequence && modalityLutModule.modalityLUTSequence.length > 0 && isModalityLUTForDisplay(sopCommonModule.sopClassUID)) { image.modalityLUT = modalityLutModule.modalityLUTSequence[0]; } // VOI LUT if (voiLutModule.voiLUTSequence && voiLutModule.voiLUTSequence.length > 0) { image.voiLUT = voiLutModule.voiLUTSequence[0]; } // set the ww/wc to cover the dynamic range of the image if no values are supplied if (image.windowCenter === undefined || image.windowWidth === undefined) { if (image.color) { image.windowWidth = 255; image.windowCenter = 128; } else { const maxVoi = image.maxPixelValue * image.slope + image.intercept; const minVoi = image.minPixelValue * image.slope + image.intercept; image.windowWidth = maxVoi - minVoi; image.windowCenter = (maxVoi + minVoi) / 2; } } return image; } export default createImage;