/*========================================================================= Program: gdcm Module: $RCSfile: Volume2Dicom.cxx,v $ Language: C++ Date: $Date: 2004/12/04 08:46:10 $ Version: $Revision: 1.1 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /** * This example was proposed by Jean-Michel Rouet * It was patch by Mathieu Malaterre to remove ITK reference and be more * independant from other toolkit * It's aim is to show people how to write their data volume into DICOM slices */ #include "gdcmHeader.h" #include "gdcmDocEntry.h" #include "gdcmBinEntry.h" #include "gdcmFile.h" #include "gdcmUtil.h" #define USAGE "USAGE: Input3DImage OutputDirectory" #include #include #include #ifdef WIN32 #define stat _stat #endif const unsigned int Dimension = 3; void gdcmwrite(const char *inputfile, std::string directory); void GetFileDateAndTime(const char *inputfile, std::string &date, std::string &time); int main( int argc, char * argv[] ) { if (argc < 2) { std::cerr << argv[0] << USAGE << std::endl; return 1; } //const char *inputfile = argv[1]; std::string directory = argv[1]; // itksys::SystemTools::ConvertToUnixSlashes( directory ); if (directory[directory.size()-1] != '/') directory += '/'; std::cout << "Converting image into dicom in " << directory << std::endl; //////////////////////////////////////////////////////////// // Reading input image and getting some information // //////////////////////////////////////////////////////////// //std::cout << "Loading image " << inputfile << std::endl; //PixelType* imageData = input->GetPixelContainer()->GetImportPointer(); uint8_t *imageData = new uint8_t[256*256*10]; memset( imageData, 0, 256*256*10); std::cout << "Image Loaded." << std::endl; int sizex = 256; int sizey = 256; int sizez = 10; float spacing[3] = { 1.0, 1.0, 1.5 }; float orig[3] = { 0.0, 0.0, 0.0 }; int sliceSize = sizex*sizey*sizeof(uint8_t); //////////////////////////////////////////////////////////// // compute window center and window width // //////////////////////////////////////////////////////////// uint8_t min, max; min = max = imageData[0]; for (int i=1; i max) max = val; if (val < min) min = val; } float wcenter = (max+min) / 2.; float wwidth = (max-min)>0 ? (max-min) : 1.; //////////////////////////////////////////////////////////// // Get file date and time // //////////////////////////////////////////////////////////// std::string filedate, filetime; //GetFileDateAndTime(inputfile, filedate, filetime); //////////////////////////////////////////////////////////// // Create a new dicom header and fill in some info // //////////////////////////////////////////////////////////// gdcm::Header *h1 = new gdcm::Header(); //h1->SetDateAndTime(filedate, filetime); //h1->SetModality("CT"); //h1->SetPatientName( "TestPatient"); //h1->SetPatientID( "TestID"); //h1->SetStudyID( "1"); //h1->SetSeriesNumber( "1"); //h1->SetSliceThickness(spacing[2]); //h1->SetSpaceBetweenSlices(spacing[2]); //h1->SetXYSpacing( spacing[0], spacing[1]); //h1->SetXSize(sizex); //h1->SetYSize(sizey); //h1->SetNbBitsAllocated(16); //h1->SetNbBitsStored(12); //h1->SetNbBitsStored(12); //h1->SetPixelSigned(true); //h1->SetCenter( wcenter); //h1->SetWindow( wwidth); //////////////////////////////////////////////////////////// // Create a new dicom file object from the header // //////////////////////////////////////////////////////////// gdcm::File *f1 = new gdcm::File(h1); uint8_t *myData = f1->GetImageData(); // Get an Image pointer f1->SetImageData( myData, sliceSize); // This callback ensures that the internal // Pixel_Data of f1 is set correctly //////////////////////////////////////////////////////////// // Iterate through the slices and save them to file // //////////////////////////////////////////////////////////// for (int z=0; zSetImageUIDFromSliceNumber(z); //h1->SetImageLocation(orig[0],orig[1],orig[2]+z*spacing[2]); // copy image slice content memcpy(myData,imageData+z*sizex*sizey,sliceSize); // write the image std::string filename = directory + gdcm::Util::Format("%Image_%05d.dcm", z); std::cout << "Writing file " << filename; f1->WriteDcmExplVR(filename); std::cout << " OK" << std::endl; } //////////////////////////////////////////////////////////// // Free the allocated objects // //////////////////////////////////////////////////////////// // delete f1; // FIXME: these calls sometimes crashes under .NET ???? // delete h1; } // just an utility function to retrieve date and time of a file void GetFileDateAndTime(const char *inputfile, std::string &date, std::string &time) { struct stat buf; if (stat(inputfile, &buf) == 0) { char tmp[512]; strftime(tmp,512,"%Y%m%d", localtime(&buf.st_mtime) ); date = tmp; strftime(tmp,512,"%H%M%S", localtime(&buf.st_mtime) ); time = tmp; } else { date = "20040101"; time = "120000"; } }