2

I am trying to display image data from a DICOM file. I have parsed the file and extracted the 16 bit greyscale image into a Uint16Array. I think it is a convenient format if I want to pass this to WebGL as a texture, but what to do if I want to paste this onto a canvas ?

Thanks.

xperien
  • 43
  • 5
  • You'll get the job done with putImageData. – GameAlchemist Oct 24 '14 at 10:48
  • Thanks for the tip. Right now, I make a new Uint8ClampedArray and run a loop to put all the data from the Uint16Array into the new Array. Then I use the putImageData function to paste it onto the canvas. Do you know if this is the only way because the loop is quite expensive ? – xperien Oct 27 '14 at 07:18
  • So you have an answer : you should post it below. I'll see if there are possible improvements. I wonder if taking a Uint32 view on the array and dealing with bytes 4 by 4 could speed up things (var view32 = new Uint32Array(imgdata.data.buffer) ). (But this wouldn't work in FF...) And don't forget to create only once the imgData, then re-use, creation is very long. – GameAlchemist Oct 27 '14 at 09:25

2 Answers2

2

Thanks @GameAlchemist.

I found this to work for me.

// get the image data (16 bit unsigned array of intensities) from the ArrayBuffer
pixelData = new Uint8Array(arraybuffer, frameOffset, numPixels);

// set up canvas
var imageCanvas = document.getElementById('canvas_1');
imageCanvas.setAttribute("width", rows);
imageCanvas.setAttribute("height", columns);
var ctx = imageCanvas.getContext('2d');

// imageData is Uint8ClampedArray
var imageData = ctx.getImageData(0, 0, imageCanvas.width, imageCanvas.height);

// this part seems slow :( 
for(var i = 0; i < numPixels; i++) {
    imageData.data[4*i] = (pixelData[i]*255)/4095;
    imageData.data[4*i+1] = (pixelData[i]*255)/4095;
    imageData.data[4*i+2] = (pixelData[i]*255)/4095;
    imageData.data[4*i+3] = 255;
}

ctx.putImageData(imageData, 0, 0);

The above works flawlessly.

Is there something that I am missing which can make it faster ?

xperien
  • 43
  • 5
1

Here is my code with a Uint8Array displayBuffer existing variable. Instead of the loop, you can use the data.set() magic:

            var tlCanvas = document.getElementById("tlCanvas");
            tlCanvas.width = width;   // width defined in displayBuffer
            tlCanvas.height = height; // height defined in displayBuffer

            var tlCtx = tlCanvas.getContext('2d');
            var imgData= tlCtx.createImageData(width, height)
            imgData.data.set(displayBuffer); 
            tlCtx.putImageData(imgData, 0, 0); 

Some complement info here: How to create a new ImageData object independently?

thomasL
  • 641
  • 7
  • 7