dicom文件与bmp和jpg文件的相互转化

        前面工作需要,将dicom医学文件转化为普通图像,如bmp,jpg等,中间应用到了CxImage_x64和dcmtk包。实现过程中,遇到了不少麻烦,现将相关过程分享如下,希望能给需要的人提供参考,以及上传所有相关文档。


文档分为以下几部分:

(1)      工程文件,需要将支持库拷贝到对应位置,并设置工程库目录,包含目录之后才能运行;

(2)      可执行文件,拷贝到64位机器即可运行(其中包含医学影像文件image-000001.dcm);

(3)      支持库:用于打开解析dicom文件,需要按照说明添加;

(4)      Readme.doc:描述文档结构和配置,代码,程序界面等信息。

1、支持库拷贝

先按照支持库里面说明,将两个包拷贝到常用位置,方便后面设置工程,具体可以参照我的设置测试方式。

 

2、工程设置

包含目录设置:

D:\Program Files (x86)\Microsoft VisualStudio 10.0\CxImage_x64\include(如果是32位自己下32位版本

D:\Program Files\DCMTK\include

 dicom文件与bmp和jpg文件的相互转化_第1张图片

库目录设置:

D:\Program Files (x86)\Microsoft VisualStudio 10.0\CxImage_x64\lib

D:\Program Files\DCMTK\lib

 

连接器附加项设置:

cximage.lib

netapi32.lib

wsock32.lib

ofstd.lib

oflog.lib

dcmimgle.lib

ijg8.lib

ijg12.lib

ijg16.lib

dcmdata.lib

dcmimage.lib

dcmjpeg.lib

dcmnet.lib


3、工程字符集设为多字节

4、核心代码简单说明

4.1、选择文件

    TCHAR szFilter[] = _T("文本À文件t(*.dcm)|*.dcm");  //选择dcm文件打开

    CFileDialog fileDlg(TRUE,_T("txt"),NULL, 0, szFilter,this);// 创建对话框 

    CStringstrFilePath;  

    if (IDOK ==fileDlg.DoModal())   // 点击确定保存文件路径

    {  

        strFilePath =fileDlg.GetPathName();   // 文件路径

        SetDlgItemText(IDC_EDIT_open,strFilePath);   // 设置文件路径显示与界面

         

        savepath = fileDlg.GetFolderPath(); // 生存图像保存路径

        filename= fileDlg.GetFileTitle();   // 生存图像保存文件名

 

    }  

 

4.2、打开并转化文件

if ((m_check_bmp.GetCheck()>0)||(m_check_jpg.GetCheck()>0)) // 指定需要转化的图片类型,目前只提供bmP和jpg

    {

        CString str,savestr;  //

        GetDlgItem(IDC_EDIT_open)->GetWindowText(str);  // 获取文件名

        DJEncoderRegistration::registerCodecs();//注册dicom文件封装类

        DcmFileFormat fileformat;

        if(fileformat.loadFile(str).good()) // 文件加载正常

        {      

            THU_STD_NAMESPACE::TDcmFileFormattdf(fileformat); // 转化为封装类

            if (m_check_bmp.GetCheck()>0)

            { // 如果选择了bmp转化

                tdf.saveToBmp(savepath+"\\"+filename+".bmp");   // 转化为bmp文件,具体代码可以点击函数定义进去查看,主要步骤包括将dcom文件的头文件信息以及数据索引指针赋值给bmp对象,在进行保存,jpg类似

            }

            if(m_check_jpg.GetCheck()>0)

            {

                tdf.saveToJpg(savepath+"\\"+filename+".jpg");//  转化为jpg文件

            }

 

                inth = tdf.getHeight();  // 获取影像高度

            int w = tdf.getWidth(); //获取影像宽度

            CStringstr ;

            str.Format("%d",w);

            SetDlgItemText(IDC_ew,str);  //宽度显示于界面

            str.Format("%d",h);

            SetDlgItemText(IDC_eh,str);  //高度显示

        MessageBox("转化完毕!","提示"); // 信息提示

        }

        DJEncoderRegistration::cleanup();//注销注册类

    }

    else

        MessageBox("请选择转化类型","提示");

4.3、显示图像

void Cdicomview20170310Dlg::OnBnClickedshowpic()

{

    int cx, cy

    CImage  image

    CRect   rect

    if (PathFileExists(savepath+"\\"+filename+".bmp"))// 判断图像是否存在

    {

        image.Load(savepath+"\\"+filename+".bmp"); // 加载图像

    } else if ( PathFileExists(savepath+"\\"+filename+".jpg" ))

    {

        image.Load(savepath+"\\"+filename+".jpg");   // 加载图像

    }

    else

        return;

 

    cx  =image.GetWidth();   // 获取图像宽高

    cy  = image.GetHeight(); 

 

    GetDlgItem(IDC_pic)->GetWindowRect(&rect);  // 获取显示控件区域

    ScreenToClient(&rect); 

    GetDlgItem(IDC_pic)->MoveWindow(rect.left, rect.top,cx,cy,TRUE);  // 移动到指定区域

    CWnd *pWnd= NULL

    pWnd    = GetDlgItem(IDC_pic);//获取显示控件句柄

    pWnd->GetClientRect(&rect);//获取句柄对应区域

 

    CDC *pDc = NULL

    pDc = pWnd->GetDC();//显示图像

 

    image.Draw(pDc->m_hDC,rect);//绘制图像

    ReleaseDC(pDc);  // 释放资源

}

 

4.4、bmp转dcm

OFConditionstatus;  // 定义变量

    DcmFileFormat fileformat; 

    DcmDataset*mydatasete=fileformat.getDataset();

    DicomUtils du;

    du.AddDicomElements((DcmDataset*&)mydatasete); 

    Uint16 rows,cols,samplePerPixel,bitsAlloc,bitsStored,highBit,pixelRpr,planConf,pixAspectH,pixAspectV; 

    OFString photoMetrInt; 

    Uint32 length; 

    E_TransferSyntax ts; 

    //-¡¤¬¨ª¨®4?ª?

    //for(inti=0;i<4;++i) 

    //{ 

        charnumtmp[500];  // 申明文件名字符串

        CString tpath = savepath+"\\"+filename+".bmp"  ;

        memset(numtmp,0,sizeof(tpath));

        sprintf(numtmp,"%s",tpath);//转化文件名字符串

        I2DBmpSource *bmpSource = new I2DBmpSource();//I2DBmpSource();

        bmpSource->setImageFile(numtmp);  // 读取bmp图像数据

 

        char*pixData=NULL; 

bmpSource->readPixelData(rows,cols,samplePerPixel,photoMetrInt,bitsAlloc,bitsStored,highBit,pixelRpr,planConf,pixAspectH,pixAspectV,pixData,length,ts);  // 解析图像数据

        //deletebmpSource; 

    //}; 

    mydatasete->putAndInsertUint16(DCM_SamplesPerPixel,samplePerPixel);  // 添加bmp图像数据到dcm文件

    mydatasete->putAndInsertString(DCM_NumberOfFrames,"1"); 

    mydatasete->putAndInsertUint16(DCM_Rows,rows); 

    mydatasete->putAndInsertUint16(DCM_Columns,cols); 

    mydatasete->putAndInsertUint16(DCM_BitsAllocated,bitsAlloc); 

    mydatasete->putAndInsertUint16(DCM_BitsStored,bitsStored); 

    mydatasete->putAndInsertUint16(DCM_HighBit,highBit); 

    mydatasete->putAndInsertUint8Array(DCM_PixelData,(Uint8*)pixData,1*length); 

    mydatasete->putAndInsertOFStringArray(DCM_PhotometricInterpretation,photoMetrInt); 

    mydatasete->putAndInsertString(DCM_PlanarConfiguration,"1");

    tpath = savepath+"\\"+filename+"new.dcm"  ;

    memset(numtmp,0,sizeof(tpath));

    sprintf(numtmp,"%s",tpath);

    status=fileformat.saveFile(numtmp,ts);  //保存dcm文件

    if(status.bad())    // 保存状态

    { 

        MessageBox("Áa?º¡ì㨹ê?","¬¨¢º?");

    }  else {

        MessageBox("Áa?ª¨ºÀ?ê?","¬¨¢º?");

    }

 

5、程序效果

步骤分3步:
(1)点击打开文件,选择待转化文件;

(2)选择jpg或者bmp待转化格式;

(3)点击转换;

(4)显示转化图像的效果;

(5)退出;

 

转化生成的图片保存在原始影像文件所在目录,如下图所示:



你可能感兴趣的:(vc++,医学图像dcom,dcmtk,cximage)