dicomParser
dicomParser copied to clipboard
How to convert DICOM to jpg or png?
So far I haven't been able to figure this out. The examples on the sample pages weren't working for me (at least not MacOS Safari & Chrome)
The following bit of code seems to work (or at least produces no errors) but the final step attempting generating a png or jpg from pixelDataBuffer does't properly generate the desired file.
fs=require("fs");
dicomParser=require("dicom-parser");
dicomData=fs.readFileSync("/path/to/DicomFile");
dicomParsed=dicomParser.parseDicom(dicomData);
pixelData = dicomParsed.elements.x7fe00010;
pixelDataBuffer = dicomParser.sharedCopy(dicomData, pixelData.dataOffset, pixelData.length);
fs.writeFileSync("/path/to/File.png", pixelDataBuffer); // Doesn't work. Nor does jpg, so no doubt there's more to all this.
I'm not sure raw DICOM pixel data is suitable for PNG or JPEG.
@AntonOnyshch is correct. You'd need to use a library like pngjs to take in the bytes and save to png. For a basic greyscale image, that might work almost right out of the box, but there's potential for needing to convert the pixels as stored in the DICOM to something PNG understands. If you need to do that conversion, you'll need to read up on samples per pixel, planar configuration, etc.(you can find a good run down here).
@communque If terms like "samples per pixel", "high bit" and other tags seems to be complicated for you I could help you grasp this concept as much as I can. I just need to know your initial understanding level.
This is also a great resource to better understand pixels in DICOM.
Any updates? i have the same problem and dont find any solution
I need to convert the parsedDicom into a base64 png
What do you want to be converted? Whole *dcm file or bunch of pixels in it?
@AntonOnyshch is it possible to convert data under tag "Pixel data" to jpg or any picture format, if it is how can we do that? Right now I get 500k pixels in an array but when I try to convert it to Image, I get an exception Invalid image data
@asimceman did you pass your pixels through look up table before converting them?
@AntonOnyshch No, I havent. What kind of look up table? Can I find any documentation about that? Thanks for your response :)
@asimceman Here is documentation
Normally, in dentistry pixels data is in 16 bit range. You should convert your pixel by this formula: pixel value*Rescale Slope+Rescale Intercept. The pixel you get is ready for look up table(LUT). LUT is just an array that contains values from 0 to 255.
Typescript
export function calculateLUT(windowWidth: number, windowCenter: number): Uint8ClampedArray {
const lut = new Uint8ClampedArray(windowWidth);
const wW = windowWidth - 1;
const wC = windowCenter - 0.5;
const min = wC - wW / 2;
const max = wC + wW / 2;
const factor = 255 / (max - min);
for (let i = 0; i < lut.length; ++i) {
if (i <= min)
lut[i] = 0;
else if (i >= max)
lut[i] = 255;
else
lut[i] = (i - min) * factor;
}
return lut;
}
But your converted pixel always be from -1000 to 4000 for example. So I do not use "+ Rescale Intercept"(actually you should) which generally negative and therefore I can pass it through LUT indices(which only positive). LUT may be from 0 to 5000. And -1000 is 0, -500 is 500 in LUT index.
lutValue = lut[pxlBuffer[dataOffset + dataPxl] * meta.rescaleSlope];
@AntonOnyshch thank you for your help!