Visual C++/DCMTK with CxImage

DCMTK with CxImage in MFC

Soul-Learner 2013. 7. 11. 10:34

DCMTKDCMTK가 다루는 DCM 이미지의 DIB 비트맵핸들을 CxImage.CreateFromHBITMAP(HBITMAP) 함수의 파라미터로 전달하면 CxImage에 의해 DCM 이미지의 영상처리가 가능하다. 

아래 코드 중에서 하늘색 배경으로 설정된 코드는 DCMTK와 CxImage 가 연결되는 부분이다

DicomImage *ptrDicomImage = NULL;

void* data = NULL;

BITMAPINFO bi;

HBITMAP hbmp = 0;


void CDCMTK_IMG_OutputView::OnDraw(CDC* pDC)

{

CDCMTK_IMG_OutputDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;


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


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

LPCTSTR lpstrFile = _T("D:\\test\\샘플2.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();


/*

//환자의 이름을 가져와서 메시지박스에 출력하는 예

TCHAR tagValue[128];

DcmMetadata::Get(ptrDcmFileFormat, DCM_PatientName, tagValue);

//AfxMessageBox(tagValue);

*/


//주요한 메타데이타 5개를 PatientVO에 저장하여 리턴하는 예

PatientVO patientVO = DcmMetadata::GetMain(ptrDcmFileFormat);

/*

CString info;

info.Format(_T("%s, %s, %s, %s, %s"), patientVO.patientName, patientVO.patientID, 

patientVO.patientSex, patientVO.studyDate, patientVO.institutionName);

AfxMessageBox(info);

*/

//dcm 파일의 모든 태그정보를 추출하는 예

/*

int tagCount = 0;

TagVO* tags = DcmMetadata::GetAllTags(ptrDcmFileFormat, &tagCount);

for(int i=0;i<tagCount;i++)

{

CString msg;

msg.Format(_T("%s, %s, %s, %s"), tags[i].tstrTagName, tags[i].tstrTagCode, tags[i].tstrVRName, tags[i].tstrTagValue);

AfxMessageBox(msg);

}

delete [] tags;

*/


if(ptrDicomImage==NULL)

                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();


int nResult = ptrDicomImage->setMinMaxWindow();


if(data==NULL) 

{

ptrDicomImage->createWindowsDIB(data, width*height);

if(data!=NULL) // 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 는 사용후 반드시 해제해야 함

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


// CxImage를 이용하는 예

CxImage cximage;

cximage.CreateFromHBITMAP(hbmp);

//cximage.Mirror();

//cximage.Flip();

//cximage.Rotate180();

//cximage.Resample(width*2.0, height*2.0, 2);

//hbmp = cximage.MakeBitmap();

BOOL savedOK = CxImageDCM::ConvertIntoJPG(hbmp, (TCHAR*)lpstrFile);

if(savedOK)

{

AfxMessageBox(_T("변환 성공"));

}

else

{

AfxMessageBox(_T("변환 실패"));

}


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);


//그림 위에 텍스트 출력

DcmMetadata::PrintPatientVO(pDC, &patientVO, width);


// 이미지의 크기를 스크롤바가 보여지는 화면의 크기로 설정한다

CSize imgSize;

imgSize.cx = width;

imgSize.cy = height;

SetScrollSizes(MM_TEXT, imgSize);


DeleteDC(memDC); 

DeleteObject(hbmp);

}

//delete data;

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

}