본문 바로가기

Visual C++/DCMTK, dcm drawing

DCMTK, Image Drawing Example

VC++ 2012, DCMTK 3.6.1을 이용한 DICOM 이미지 화면 출력 예제


VC에서 DCMTK 라이브러리를 설정하는 예를 먼저 참고해주세요


테스트환경

 - Windows 7

 - VC++ 2012

 - DCMTK 3.6.1


개요

VC++ 2012와 DCMTK 3.6.1 을 이용하여 화면에 DICOM(*.dcm) 이미지를 출력한다


작업순서 (아래 1~3번까지의 작업은 위의 링크를 참조하면 된다 )

1. DCMTK 3.6.1 의 소스코드를 다운로드하여 VC++ 2012에서 컴파일하여 라이브러리(dcmtk.lib, dcmtk.dll)를 생성한다

2. VC++ 2012에서 MDI 프로젝트를 생성하고, 그 프로젝트에 DCMTK 라이브러리(dcmtk.lib)와 헤더파일을 등록한다

3. 생성된 프로젝트의 Debug 혹은 Release 폴더 안에 dcmtk.dll 파일을 복사해 넣는다

4. *View.cpp 파일을 열고 DCMTK 헤다파일을 include 하고 DCMTK 정적라이브러리를 링크설정한다

5. *View.cpp 의 OnDraw() 함수 안에 화면 출력용 코드를 작성한다

6. 샘플 dcm 파일을 준비하고 프로젝트를 빌드하여 화면에 DCM 이미지가 출력되는지 확인한다


*View.cpp 파일에 헤더파일과 정적라이브러리 설정

// DCMTK_Image_OutputView.cpp : CDCMTK_Image_OutputView 클래스의 구현

//


#include "stdafx.h"


#include "dcmtk/config/osconfig.h"

#include "dcmtk/dcmdata/dctk.h"

#include "dcmtk/dcmimgle/dcmimage.h"

#include "dcmtk/dcmjpeg/djutils.h"

#include "dcmtk/dcmjpeg/djdecode.h"



#pragma comment(lib, "dcmtk.lib")




*View.cpp 의 OnDraw() 안에 다음과 같이 화면 출력용 코드를 작성한다

void CDCMTK_Image_OutputView::OnDraw(CDC* pDC)

{

CDCMTK_Image_OutputDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;


// TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.


LPCTSTR lpstrFile = _T("D:\\test\\sample.dcm");


USES_CONVERSION;


char* filename = W2A(lpstrFile);


DcmFileFormat* ptrDcmFileFormat = new DcmFileFormat();

OFCondition cond = ptrDcmFileFormat->loadFile(filename);

if (cond.good())

{

//AfxMessageBox(_T("DCM파일 로드성공"));

}

else if(cond.bad())

{

AfxMessageBox(_T("DCM파일 로드실패"));

exit(0);

}


DJDecoderRegistration::registerCodecs(); // register JPEG codecs

DcmDataset *dataset = ptrDcmFileFormat->getDataset();


// decompress data set if compressed

dataset->chooseRepresentation(EXS_LittleEndianExplicit,NULL);


E_TransferSyntax xfer = ptrDcmFileFormat->getDataset()->getOriginalXfer();


        DicomImage *ptrDicomImage = new DicomImage(ptrDcmFileFormat, xfer, CIF_AcrNemaCompatibility, 0, 1);


if(ptrDicomImage != NULL)

{

//AfxMessageBox(_T("DicomImage 인스턴스 생성 성공"));

}

else

{

AfxMessageBox(_T("DicomImage 인스턴스 생성 실패"));

exit(0);

}


if(ptrDicomImage->getStatus()!= EIS_Normal) exit(0);


int width  = (int)ptrDicomImage->getWidth();

int height = (int)ptrDicomImage->getHeight();

void *data = NULL; 


int nResult = ptrDicomImage->setMinMaxWindow();


if(ptrDicomImage->createWindowsDIB(data, width*height) && data) // data 는 사용후 반드시 해제해야 함

{

BITMAPINFO bi; 

bi.bmiHeader.biSize        = sizeof(bi); 

bi.bmiHeader.biWidth       = width; 

bi.bmiHeader.biHeight      = -height; 

bi.bmiHeader.biPlanes      = 1; 

bi.bmiHeader.biBitCount    = 24; 

bi.bmiHeader.biCompression = BI_RGB;

bi.bmiHeader.biSizeImage   = 0;


// hbmp 는 사용후 반드시 해제해야 함

HBITMAP hbmp = CreateDIBitmap(pDC->GetSafeHdc(), &bi.bmiHeader, CBM_INIT, data, &bi, DIB_RGB_COLORS);

if(hbmp)

 HDC memDC = CreateCompatibleDC(pDC->GetSafeHdc()); // memDC 는 사용후 반드시 해제해야 함

 SelectObject(memDC, hbmp); 

 

 SetStretchBltMode(memDC, HALFTONE);

 StretchBlt(pDC->GetSafeHdc(), 0, 0, width, height,

  memDC, 0, 0, width, height, SRCCOPY);

 DeleteDC(memDC); 

 DeleteObject(hbmp);

}

}

//delete data;

}



테스트용 dcm 파일

sample.dcm


프로그램 실행화면