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 파일
프로그램 실행화면