使用HTML5画布和Javascript显示多帧dicom图像

使用HTML5画布和Javascript显示多帧dicom图像,javascript,html,canvas,dicom,fileparsing,Javascript,Html,Canvas,Dicom,Fileparsing,我正在尝试使用HTML5画布和javascript在浏览器中显示多帧dicom图像。到目前为止,我可以渲染单帧图像,但我有多帧图像的问题 为了解析文件,我正在使用插件 当我将数据分解成片段(帧)并尝试显示它们时,画布只会渲染噪声条。以下是从多帧图像渲染单个帧的示例 下面是脚本代码 // CREATE A CANVAS REFERENCE // ----------------------------------------------------------------------------

我正在尝试使用HTML5画布和javascript在浏览器中显示多帧dicom图像。到目前为止,我可以渲染单帧图像,但我有多帧图像的问题

为了解析文件,我正在使用插件

当我将数据分解成片段(帧)并尝试显示它们时,画布只会渲染噪声条。以下是从多帧图像渲染单个帧的示例

下面是脚本代码

// CREATE A CANVAS REFERENCE
// -------------------------------------------------------------------------------------------------
var canvas = document.getElementById( 'canvas' );
canvas.with = 200;
canvas.height = 200;


// ADD A HANDLER FOR READING FILES FROM COMPUTER
// -------------------------------------------------------------------------------------------------
var dicomFile = document.getElementById( 'dicomfile' );

dicomFile.onchange = function( evt ) {
    var tgt = evt.target || window.event.srcElement,
        files = tgt.files;


// FILEREADER SUPPORT
// ---------------------------------------------------------------------------------------------
if ( FileReader && files && files.length ) {
    var fr = new FileReader(),
        extension = files[ 0 ].name.split( '.' ).pop().toLowerCase();

    // IF EXTENSION IS NOT DCM ,THEN STOP PROCESSING FURTHER AND EXIT.
    if ( extension !== 'dcm' ) {
        alert( 'please choose a Dicom file' );
        return;
    } else {

        // PARSE AND PROCESS THE DICOM FILE.
        fr.onload = function( e ) {

            var dicomArray = new Uint8Array( e.target.result ), 

                // PARSE THE DICOM FILE
                dataSet = dicomParser.parseDicom( dicomArray ),

                // GET WIDTH AND HEIGHT OF THE DICOM IMAGE.
                width = dataSet.uint16( 'x00280011' ), height = dataSet.uint16( 'x00280010' ),

                // GET THE PIXEL DATA ELEMENT FROM THE DATASET.
                pixelDataElement = dataSet.elements.x7fe00010;

            // NOW GET THE PIXEL DATA FROM THE DICOM FILE.
            var pixelData = [];

            pixelDataElement.basicOffsetTable.forEach( function(offset){ 
                pixelDataElement.fragments.forEach(function(fragment){
                    pixelData.push( new Uint8Array( dataSet.byteArray.buffer, offset, fragment.length ) );
                });
            });

            // NOW WE HAVE GOT WIDTH, HEIGHT AND PIXEL DATA WHICH IS ALL IT TAKES TO RENDER A IMAGE TO THE CANVAS.
            canvas.width = width;
            canvas.height = height;

            // GET CONTEXT
            var context = canvas.getContext( '2d' ),

            // GET IMAGE DATA TO UPDATE
                imageData = context.getImageData( 0, 0, width, height ),
                data = imageData.data;

            // UPDATING ALPHA
            for ( var i = 3, k = 0; i < data.byteLength; i = i + 4, k = k + 2 ) {

                // CONVERT 16-BIT TO 8-BIT ,BECAUSE WE CANNOT RENDER A 16-BIT VALUE TO THE CANVAS.
                var result = ((pixelData[0][ k + 1 ] & 0xFF) << 8) | (pixelData[0][ k ] & 0xFF);
                result = (result & 0xFFFF) >> 8;
                data[ i ] = 255 - result;
            }

            imageData[0] =  data[0];

            context.putImageData( imageData, 0, 0 );

            // SHOW THE CANVAS
            canvas.style.display = 'block';
        };
        fr.readAsArrayBuffer( this.files[ 0 ] );
    }
}
};
//创建画布引用
// -------------------------------------------------------------------------------------------------
var canvas=document.getElementById('canvas');
canvas.with=200;
画布高度=200;
//添加用于从计算机读取文件的处理程序
// -------------------------------------------------------------------------------------------------
var dicomFile=document.getElementById('dicomFile');
dicomFile.onchange=函数(evt){
var tgt=evt.target | | window.event.src元素,
files=tgt.files;
//文件阅读器支持
// ---------------------------------------------------------------------------------------------
if(FileReader&&files&&files.length){
var fr=new FileReader(),
扩展名=文件[0].name.split('.').pop().toLowerCase();
//如果扩展不是DCM,则进一步停止处理并退出。
如果(扩展名!==“dcm”){
警报(“请选择Dicom文件”);
返回;
}否则{
//解析并处理DICOM文件。
fr.onload=功能(e){
var dicomArray=新的UINT8阵列(如target.result),
//解析DICOM文件
数据集=dicomParser.parseDicom(dicomArray),
//获取DICOM图像的宽度和高度。
宽度=dataSet.uint16('X002800011'),高度=dataSet.uint16('X002800010'),
//从数据集中获取像素数据元素。
pixelDataElement=dataSet.elements.x7fe00010;
//现在从DICOM文件中获取像素数据。
var pixelData=[];
pixelDataElement.basicOffsetTable.forEach(函数(偏移量){
pixelDataElement.fragments.forEach(函数(fragment){
push(新的Uint8Array(dataSet.byteArray.buffer,offset,fragment.length));
});
});
//现在,我们已经获得了宽度、高度和像素数据,这是将图像渲染到画布所需的全部数据。
画布宽度=宽度;
canvas.height=高度;
//获取上下文
var context=canvas.getContext('2d'),
//获取要更新的图像数据
imageData=context.getImageData(0,0,宽度,高度),
data=imageData.data;
//更新ALPHA
对于(变量i=3,k=0;i8;
数据[i]=255——结果;
}
imageData[0]=数据[0];
putImageData(imageData,0,0);
//展示画布
canvas.style.display='block';
};
fr.readAsArrayBuffer(this.files[0]);
}
}
};
有谁能告诉我哪里出了问题。任何信息,无论多么笼统,都会有帮助


最终目标是将这些帧用作webGl和three.js的纹理,以创建dicom图像的体积渲染

多帧文件中的图像帧可能已压缩,并且dicomParser不包含解压缩代码。请查看CornerstoneWADOImageLoader for codec以及如何使用它们:

感谢您推荐此图像加载器,到目前为止,它看起来比dicomParser更健壮。虽然还处于早期阶段,但我希望它能与webGL/three.jsYup一起使用,它看起来相当不错。我们能够以相对较少的麻烦创建图像堆栈。您对图像压缩的看法也是正确的。