JPEG转为DICOM文件
1 //====================================================================================== 2 // NanJing ChunRen L.T.D 3 // Created by HGB 4 //====================================================================================== 5 /*convert.h*/ 6 7 8 #ifdef __cplusplus 9 extern "C" { 10 #endif 11 12 13 // 下列部分用于定义SCU/SCP回调函数 14 15 //typedef void (__stdcall * STORESCPCALLBACK)(T_StoreProgress* progress, LPCSTR filename); 16 17 // 下列函数用于处理SCU高级网络服务 18 /*BOOL __stdcall dicom_echoscu_execute(LPCSTR servername, int serverport, 19 LPCSTR servertitle, LPCSTR clienttitle); 20 BOOL __stdcall dicom_storescu_execute(LPCSTR servername, int serverport, 21 LPCSTR servertitle, LPCSTR clienttitle, 22 LPCSTR filelist, STORESCUCALLBACK callback);*/ 23 24 // 下列函数用于处理SCP高级网络服务 25 //int __declspec(dllexport) IncInt(int params); 26 bool __stdcall jpg2dcm(LPSTR BmpSrc, LPSTR DcmDest, LPSTR PatientName, LPSTR PatientSex); 27 //int __stdcall(dllexport) IncInt(int params); 28 29 30 #ifdef __cplusplus 31 } 32 #endif 33 34 35 #ifdef __cplusplus 36 37 extern "C" { 38 #endif 39 40 41 // 下列部分用于定义SCU/SCP回调函数 42 43 //typedef void (__stdcall * STORESCPCALLBACK)(T_StoreProgress* progress, LPCSTR filename); 44 45 // 下列函数用于处理SCU高级网络服务 46 /*BOOL __stdcall dicom_echoscu_execute(LPCSTR servername, int serverport, 47 LPCSTR servertitle, LPCSTR clienttitle); 48 BOOL __stdcall dicom_storescu_execute(LPCSTR servername, int serverport, 49 LPCSTR servertitle, LPCSTR clienttitle, 50 LPCSTR filelist, STORESCUCALLBACK callback);*/ 51 52 // 下列函数用于处理SCP高级网络服务 53 //int __declspec(dllexport) IncInt(int params); 54 bool __stdcall jpg2dcm(LPSTR BmpSrc, LPSTR DcmDest, LPSTR PatientName, LPSTR PatientSex); 55 //int __stdcall(dllexport) IncInt(int params); 56 57 58 #ifdef __cplusplus 59 } 60 61 #endif 62 63 64 65 66 //====================================================================================== 67 // NanJing ChunRen L.T.D 68 // Created by HGB 69 //====================================================================================== 70 71 72 /*convert.cpp*/ 73 74 75 // convert.cpp : Defines the entry point for the DLL application. 76 // 77 78 #include "stdafx.h" 79 //#include <afx.h> 80 #include "convert.h" 81 #include "xImageDCM.h" 82 83 BOOL APIENTRY DllMain( HANDLE hModule, 84 DWORD ul_reason_for_call, 85 LPVOID lpReserved 86 ) 87 { 88 switch (ul_reason_for_call) 89 { 90 case DLL_PROCESS_ATTACH: 91 case DLL_THREAD_ATTACH: 92 case DLL_THREAD_DETACH: 93 case DLL_PROCESS_DETACH: 94 break; 95 } 96 return TRUE; 97 } 98 99 100 int IncInt(int params) 101 { 102 return params+1; 103 } 104 105 106 bool __stdcall jpg2dcm(LPSTR BmpSrc, LPSTR DcmDest, LPSTR PatientID, LPSTR PatientName, 107 LPSTR PatientSex, LPSTR StudyDate) 108 { 109 CxImageDCM dcm; 110 //CString m_sBmpSrcFile; 111 //CString m_sDcmDestFile; 112 //dcm.Load(BmpSrc,CXIMAGE_FORMAT_BMP); 113 dcm.Load(BmpSrc,CXIMAGE_FORMAT_JPG); 114 if(!dcm.IsValid()){ 115 return false; 116 }else{ 117 /*m_sBmpSrcFile=filename; 118 m_sDcmDestFile=m_sBmpSrcFile; 119 m_sDcmDestFile.TrimRight(filename); 120 m_sDcmDestFile+=_T("dcm");*/ 121 //if(dcm.SaveAsDCM(m_sDcmDestFile)) 122 if(dcm.SaveAsDCM(DcmDest, PatientID, PatientName, PatientSex, StudyDate)) 123 { 124 return true; 125 } 126 else 127 { 128 return false; 129 } 130 } 131 } 132 133 134 135 136 //====================================================================================== 137 // NanJing ChunRen L.T.D 138 // Created by HGB 139 //====================================================================================== 140 141 // xImageDCM.cpp: implementation of the CxImageDCM class. 142 // 143 ////////////////////////////////////////////////////////////////////// 144 #include "StdAfx.h" 145 //#include "DCMConverter.h" 146 #include "xImageDCM.h" 147 148 149 #include "osconfig.h" /* make sure OS specific configuration is included first */ 150 151 152 #ifdef HAVE_GUSI_H 153 #include <GUSI.h> 154 #endif 155 156 #include "dctk.h" /* for various dcmdata headers */ 157 #include "dcdebug.h" /* for SetDebugLevel */ 158 #include "cmdlnarg.h" /* for prepareCmdLineArgs */ 159 #include "dcuid.h" /* for dcmtk version name */ 160 #include "dcrledrg.h" /* for DcmRLEDecoderRegistration */ 161 162 #include "dcmimage.h" /* for DicomImage */ 163 #include "digsdfn.h" /* for DiGSDFunction */ 164 #include "diciefn.h" /* for DiCIELABFunction */ 165 166 #include "ofconapp.h" /* for OFConsoleApplication */ 167 #include "ofcmdln.h" /* for OFCommandLine */ 168 169 #include "diregist.h" /* include to support color images */ 170 #include "ofstd.h" /* for OFStandard */ 171 172 #include "djdecode.h" /* for dcmjpeg decoders */ 173 #include "dipijpeg.h" /* for dcmimage JPEG plugin */ 174 #include "dipitiff.h" /* for dcmimage TIFF plugin */ 175 #include "dipipng.h" /* for dcmimage PNG plugin */ 176 #include "zlib.h" /* for zlibVersion() */ 177 178 #include "ofstream.h" 179 180 181 /*#ifdef _DEBUG 182 #undef THIS_FILE 183 static char THIS_FILE[]=__FILE__; 184 #define new DEBUG_NEW 185 #endif*/ 186 187 188 189 190 ////////////////////////////////////////////////////////////////////// 191 // Construction/Destruction 192 ////////////////////////////////////////////////////////////////////// 193 194 CxImageDCM::CxImageDCM() 195 { 196 //init pointers 197 pDib = pSelection = pAlpha = NULL; 198 pLayers = NULL; 199 //init structures 200 memset(&head,0,sizeof(BITMAPINFOHEADER)); 201 memset(&info,0,sizeof(CXIMAGEINFO)); 202 //init default attributes 203 info.dwType = 0; 204 info.nQuality = 90; 205 info.nAlphaMax = 255; 206 info.nBkgndIndex = -1; 207 info.bEnabled = true; 208 SetXDPI(96); 209 SetYDPI(96); 210 } 211 212 CxImageDCM::~CxImageDCM() 213 { 214 215 } 216 217 bool CxImageDCM::SaveAsBMP(const TCHAR *fileName) 218 {//please refer to the implementation of dcmj2pnm 219 return false; 220 } 221 222 bool CxImageDCM::SaveAsJPG(const TCHAR* fileName) 223 {//you may also use DCMTK's JPG encoding plug-in 224 return CxImage::Save(fileName,CXIMAGE_FORMAT_JPG); 225 } 226 227 bool CxImageDCM::LoadDCM(const TCHAR* filename) 228 { 229 DcmFileFormat *dfile = new DcmFileFormat(); 230 OFCondition cond = dfile->loadFile(filename, EXS_Unknown, 231 EGL_withoutGL,DCM_MaxReadLength,ERM_autoDetect); 232 233 if (cond.bad()) { 234 return false;//AfxMessageBox(cond.text()); 235 } 236 237 E_TransferSyntax xfer = dfile->getDataset()->getOriginalXfer(); 238 DicomImage *di = new DicomImage(dfile, xfer, 239 CIF_AcrNemaCompatibility , 240 0, 1); 241 242 if (di->getStatus() != EIS_Normal) 243 return false;//AfxMessageBox(DicomImage::getString(di->getStatus())); 244 245 246 247 //可改为MemoryStream操作,以替换不安全低效的临时文件 248 di->writeBMP("c:\\from_dicom.bmp",24); 249 250 return CxImage::Load("c:\\from_dicom.bmp",CXIMAGE_FORMAT_BMP); 251 252 } 253 254 bool CxImageDCM::SaveAsDCM(const TCHAR* filename, const TCHAR* PatientID, 255 const TCHAR* PatientName, const TCHAR* PatientSex, 256 const TCHAR* StudyDate) 257 { 258 CxImageDCM::IncreaseBpp(24); 259 char uid[100]; 260 DcmFileFormat fileformat; 261 DcmDataset *dataset = fileformat.getDataset(); 262 dataset->putAndInsertString(DCM_SOPClassUID, 263 UID_SecondaryCaptureImageStorage); 264 dataset->putAndInsertString(DCM_SOPInstanceUID, 265 dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)); 266 dataset->putAndInsertString(DCM_StudyInstanceUID , 267 dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)); 268 dataset->putAndInsertString(DCM_SeriesInstanceUID , 269 dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)); 270 dataset->putAndInsertString(DCM_Modality,"OT"); 271 dataset->putAndInsertString(DCM_PatientID, PatientID); 272 dataset->putAndInsertString(DCM_PatientsName, PatientName); 273 dataset->putAndInsertString(DCM_PatientsSex, PatientSex); 274 dataset->putAndInsertString(DCM_StudyDate, StudyDate); 275 dataset->putAndInsertString(DCM_WindowCenter, "256"); 276 dataset->putAndInsertString(DCM_WindowWidth, "128"); 277 278 // dataset->putAndInsertUint32(DCM_MetaElementGroupLength,128); 279 dataset->putAndInsertUint16(DCM_FileMetaInformationVersion, 280 0x0001); 281 dataset->putAndInsertString(DCM_MediaStorageSOPClassUID, 282 UID_MultiframeTrueColorSecondaryCaptureImageStorage); 283 dataset->putAndInsertString(DCM_MediaStorageSOPInstanceUID, 284 dcmGenerateUniqueIdentifier(uid,SITE_INSTANCE_UID_ROOT)); 285 dataset->putAndInsertString(DCM_TransferSyntaxUID, 286 UID_LittleEndianExplicitTransferSyntax); 287 288 /*added by HGB*/ 289 //dataset->findAndDeleteElement(DCM_ImplementationClassUID, OFTrue); 290 //dataset->findAndDeleteElement(DCM_ImplementationVersionName, OFTrue); 291 //end added 292 293 //dataset->putAndInsertString(DCM_ImplementationClassUID, 294 // dcmGenerateUniqueIdentifier(uid,SITE_INSTANCE_UID_ROOT)); 295 //dataset->putAndInsertString(DCM_ImplementationVersionName, 296 // "SEEKERSOFT1.3.01", OFTrue); 297 298 dataset->putAndInsertString(DCM_UID, 299 UID_MultiframeTrueColorSecondaryCaptureImageStorage); 300 dataset->putAndInsertUint16(DCM_SamplesPerPixel,3); 301 dataset->putAndInsertString(DCM_PhotometricInterpretation, 302 "RGB"); 303 dataset->putAndInsertUint16(DCM_SamplesPerPixel,3); 304 dataset->putAndInsertUint16(DCM_BitsAllocated,8); 305 dataset->putAndInsertUint16(DCM_BitsStored,8); 306 dataset->putAndInsertUint16(DCM_HighBit,7); 307 dataset->putAndInsertUint16(DCM_PixelRepresentation,0); 308 dataset->putAndInsertUint16(DCM_PlanarConfiguration,0); 309 dataset->putAndInsertUint16(DCM_Rows,GetHeight()); 310 dataset->putAndInsertUint16(DCM_Columns,GetWidth()); 311 //add more tags here 312 /* ... */ 313 BYTE* pData=new BYTE[GetHeight()*info.dwEffWidth]; 314 BYTE* pSrc=GetBits(head.biHeight-1); 315 BYTE* pDst=pData; 316 for(long y=0; y < head.biHeight; y++){ 317 memcpy(pDst,pSrc,info.dwEffWidth); 318 pSrc-=info.dwEffWidth; 319 pDst+=info.dwEffWidth; 320 } 321 dataset->putAndInsertUint8Array(DCM_PixelData, 322 pData, GetHeight()*info.dwEffWidth); 323 delete[] pData; 324 325 OFCondition status = fileformat.saveFile(filename, 326 EXS_LittleEndianImplicit,EET_UndefinedLength,EGL_withoutGL); 327 if (status.bad()) 328 return false;//AfxMessageBox("Error: cannot write DICOM file "); 329 330 return true; 331 }