DCMTK는 DCMTK가 다루는 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: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
}