diff --git a/Core/Code/IO/mitkImageWriter.cpp b/Core/Code/IO/mitkImageWriter.cpp index 8e2ee87636..8ec1d37459 100644 --- a/Core/Code/IO/mitkImageWriter.cpp +++ b/Core/Code/IO/mitkImageWriter.cpp @@ -1,378 +1,384 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) -Copyright (c) German Cancer Research Center, +Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkImageWriter.h" #include "mitkItkPictureWrite.h" #include "mitkImage.h" #include "mitkImageTimeSelector.h" #include "mitkImageAccessByItk.h" #include #include mitk::ImageWriter::ImageWriter() +: m_UseCompression( true ) { this->SetNumberOfRequiredInputs( 1 ); m_MimeType = ""; SetDefaultExtension(); } mitk::ImageWriter::~ImageWriter() { } void mitk::ImageWriter::SetDefaultExtension() { m_Extension = ".mhd"; } #include #include #include static void writeVti(const char * filename, mitk::Image* image, int t=0) { vtkXMLImageDataWriter * vtkwriter = vtkXMLImageDataWriter::New(); vtkwriter->SetFileName( filename ); vtkwriter->SetInput(image->GetVtkImageData(t)); vtkwriter->Write(); vtkwriter->Delete(); } #include void mitk::ImageWriter::WriteByITK(mitk::Image* image, const std::string& fileName) { // Pictures and picture series like .png are written via a different mechanism then volume images. // So, they are still multiplexed and thus not support vector images. if (fileName.find(".png") != std::string::npos || fileName.find(".tif") != std::string::npos || fileName.find(".jpg") != std::string::npos) { try { // switch processing of single/multi-component images if( image->GetPixelType(0).GetNumberOfComponents() == 1) { AccessByItk_1( image, _mitkItkPictureWrite, fileName ); } else { AccessFixedPixelTypeByItk_1( image, _mitkItkPictureWriteComposite, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES_SEQ , fileName); } } catch(itk::ExceptionObject &e) { std::cerr << "Caught " << e.what() << std::endl; } catch(std::exception &e) { std::cerr << "Caught std::exception " << e.what() << std::endl; } return; } // Implementation of writer using itkImageIO directly. This skips the use // of templated itkImageFileWriter, which saves the multiplexing on MITK side. unsigned int dimension = image->GetDimension(); unsigned int* dimensions = image->GetDimensions(); mitk::PixelType pixelType = image->GetPixelType(); mitk::Vector3D spacing = image->GetGeometry()->GetSpacing(); mitk::Point3D origin = image->GetGeometry()->GetOrigin(); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fileName.c_str(), itk::ImageIOFactory::WriteMode ); if(imageIO.IsNull()) { itkExceptionMacro(<< "Error: Could not create itkImageIO via factory for file " << fileName); } // Set the necessary information for imageIO imageIO->SetNumberOfDimensions(dimension); imageIO->SetPixelTypeInfo( pixelType.GetTypeId() ); // Set also the PixelTypeIO information since it is available after // the changes in PixelType for Bug #12838 imageIO->SetPixelType( pixelType.GetPixelTypeId() ); if(pixelType.GetNumberOfComponents() > 1) imageIO->SetNumberOfComponents( pixelType.GetNumberOfComponents() ); itk::ImageIORegion ioRegion( dimension ); for(unsigned int i=0; iSetDimensions(i,dimensions[i]); imageIO->SetSpacing(i,spacing[i]); imageIO->SetOrigin(i,origin[i]); mitk::Vector3D direction; direction.Set_vnl_vector(image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i)); vnl_vector< double > axisDirection(dimension); for(unsigned int j=0; jSetDirection( i, axisDirection ); ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i) ); ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i) ); } //use compression if available - imageIO->UseCompressionOn(); + imageIO->SetUseCompression( m_UseCompression ); imageIO->SetIORegion(ioRegion); imageIO->SetFileName(fileName); const void * data = image->GetData(); imageIO->Write(data); } void mitk::ImageWriter::GenerateData() { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } if ( m_FileName == "" ) { itkWarningMacro( << "Sorry, filename has not been set!" ); return ; } FILE* tempFile = fopen(m_FileName.c_str(),"w"); if (tempFile==NULL) { itkExceptionMacro(<<"File location not writeable"); return; } fclose(tempFile); remove(m_FileName.c_str()); - // Creating clone of input image, since i might change the geometry + // Creating clone of input image, since i might change the geometry mitk::Image::Pointer input = const_cast(this->GetInput())->Clone(); // Check if geometry information will be lost if (input->GetDimension() == 2) { if (!input->GetGeometry()->Is2DConvertable()) { MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might consider using Convert2Dto3DImageFilter before saving."; - + // set matrix to identity mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New(); affTrans->SetIdentity(); mitk::Vector3D spacing = input->GetGeometry()->GetSpacing(); mitk::Point3D origin = input->GetGeometry()->GetOrigin(); - input->GetGeometry()->SetIndexToWorldTransform(affTrans); + input->GetGeometry()->SetIndexToWorldTransform(affTrans); input->GetGeometry()->SetSpacing(spacing); input->GetGeometry()->SetOrigin(origin); } } bool vti = (m_Extension.find(".vti") != std::string::npos); // If the extension is NOT .pic and NOT .nrrd and NOT .nii and NOT .nii.gz the following block is entered if ( m_Extension.find(".pic") == std::string::npos && m_Extension.find(".nrrd") == std::string::npos && m_Extension.find(".nii") == std::string::npos && m_Extension.find(".nii.gz") == std::string::npos ) { if(input->GetDimension() > 3) { int t, timesteps; timesteps = input->GetDimension(3); ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New(); timeSelector->SetInput(input); mitk::Image::Pointer image = timeSelector->GetOutput(); for(t = 0; t < timesteps; ++t) { ::itk::OStringStream filename; timeSelector->SetTimeNr(t); timeSelector->Update(); if(input->GetTimeSlicedGeometry()->IsValidTime(t)) { const mitk::TimeBounds& timebounds = input->GetTimeSlicedGeometry()->GetGeometry3D(t)->GetTimeBounds(); filename << m_FileName.c_str() << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << m_Extension; } else { itkWarningMacro(<<"Error on write: TimeSlicedGeometry invalid of image " << filename << "."); filename << m_FileName.c_str() << "_T" << t << m_Extension; } if ( vti ) { writeVti(filename.str().c_str(), input, t); } else { WriteByITK(image, filename.str()); } } } else if ( vti ) { ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; writeVti(filename.str().c_str(), input); } else { ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; WriteByITK(input, filename.str()); } } else { // use the PicFileWriter for the .pic data type if( m_Extension.find(".pic") != std::string::npos ) { /* PicFileWriter::Pointer picWriter = PicFileWriter::New(); size_t found; found = m_FileName.find( m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle) if( m_FileName.length() > 3 && found != m_FileName.length() - 4 ) { //if Extension not in Filename ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; picWriter->SetFileName( filename.str().c_str() ); } else { picWriter->SetFileName( m_FileName.c_str() ); } picWriter->SetInputImage( input ); picWriter->Write(); */ } // use the ITK .nrrd Image writer if( m_Extension.find(".nrrd") != std::string::npos || m_Extension.find(".nii") != std::string::npos || m_Extension.find(".nii.gz") != std::string::npos ) { ::itk::OStringStream filename; filename << this->m_FileName.c_str() << this->m_Extension; WriteByITK(input, filename.str()); } } m_MimeType = "application/MITK.Pic"; try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } bool mitk::ImageWriter::CanWriteDataType( DataNode* input ) { if ( input ) { mitk::BaseData* data = input->GetData(); if ( data ) { mitk::Image::Pointer image = dynamic_cast( data ); if( image.IsNotNull() ) { //"SetDefaultExtension()" set m_Extension to ".mhd" ????? m_Extension = ".pic"; return true; } } } return false; } void mitk::ImageWriter::SetInput( DataNode* input ) { if( input && CanWriteDataType( input ) ) this->ProcessObject::SetNthInput( 0, dynamic_cast( input->GetData() ) ); } std::string mitk::ImageWriter::GetWritenMIMEType() { return m_MimeType; } std::vector mitk::ImageWriter::GetPossibleFileExtensions() { std::vector possibleFileExtensions; possibleFileExtensions.push_back(".pic"); possibleFileExtensions.push_back(".bmp"); possibleFileExtensions.push_back(".dcm"); possibleFileExtensions.push_back(".DCM"); possibleFileExtensions.push_back(".dicom"); possibleFileExtensions.push_back(".DICOM"); possibleFileExtensions.push_back(".gipl"); possibleFileExtensions.push_back(".gipl.gz"); possibleFileExtensions.push_back(".mha"); possibleFileExtensions.push_back(".nii"); possibleFileExtensions.push_back(".nrrd"); possibleFileExtensions.push_back(".nhdr"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".PNG"); possibleFileExtensions.push_back(".spr"); possibleFileExtensions.push_back(".mhd"); possibleFileExtensions.push_back(".vtk"); possibleFileExtensions.push_back(".vti"); possibleFileExtensions.push_back(".hdr"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".tif"); possibleFileExtensions.push_back(".jpg"); return possibleFileExtensions; } std::string mitk::ImageWriter::GetFileExtension() { return m_Extension; } void mitk::ImageWriter::SetInput( mitk::Image* image ) { this->ProcessObject::SetNthInput( 0, image ); } const mitk::Image* mitk::ImageWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) { return NULL; } else { return static_cast< const mitk::Image * >( this->ProcessObject::GetInput( 0 ) ); } } + +void mitk::ImageWriter::SetUseCompression( bool useCompression ) +{ + m_UseCompression = useCompression; +} diff --git a/Core/Code/IO/mitkImageWriter.h b/Core/Code/IO/mitkImageWriter.h index bd892f33b6..0443088a95 100644 --- a/Core/Code/IO/mitkImageWriter.h +++ b/Core/Code/IO/mitkImageWriter.h @@ -1,158 +1,162 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) -Copyright (c) German Cancer Research Center, +Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _MITK_IMAGE_WRITER__H_ #define _MITK_IMAGE_WRITER__H_ #include namespace mitk { class Image; /** * @brief Writer for mitk::Image * * Uses the given extension (SetExtension) to decide the format to write * (.mhd is default, .pic, .tif, .png, .jpg supported yet). * @ingroup IO */ class MITK_CORE_EXPORT ImageWriter : public mitk::FileWriter { public: mitkClassMacro( ImageWriter, mitk::FileWriter ); itkNewMacro( Self ); mitkWriterMacro; /** * Sets the filename of the file to write. * @param _arg the name of the file to write. */ itkSetStringMacro( FileName ); /** * @returns the name of the file to be written to disk. */ itkGetStringMacro( FileName ); /** * \brief Explicitly set the extension to be added to the filename. - * @param _arg to be added to the filename, including a "." + * @param _arg to be added to the filename, including a "." * (e.g., ".mhd"). */ itkSetStringMacro( Extension ); /** * \brief Get the extension to be added to the filename. - * @returns the extension to be added to the filename (e.g., + * @returns the extension to be added to the filename (e.g., * ".mhd"). */ itkGetStringMacro( Extension ); /** * \brief Set the extension to be added to the filename to the default */ void SetDefaultExtension(); /** * @warning multiple write not (yet) supported */ itkSetStringMacro( FilePrefix ); /** * @warning multiple write not (yet) supported */ itkGetStringMacro( FilePrefix ); /** * @warning multiple write not (yet) supported */ itkSetStringMacro( FilePattern ); /** * @warning multiple write not (yet) supported */ itkGetStringMacro( FilePattern ); /** * Sets the 0'th input object for the filter. * @param input the first input for the filter. */ void SetInput( mitk::Image* input ); //##Documentation //## @brief Return the possible file extensions for the data type associated with the writer virtual std::vector GetPossibleFileExtensions(); /** * @brief Return the extension to be added to the filename. */ virtual std::string GetFileExtension(); /** - * @brief Check if the Writer can write the Content of the + * @brief Check if the Writer can write the Content of the */ virtual bool CanWriteDataType( DataNode* ); /** * @brief Return the MimeType of the saved File. */ virtual std::string GetWritenMIMEType(); /** * @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function. */ virtual void SetInput( DataNode* ); /** * @returns the 0'th input object of the filter. */ const mitk::Image* GetInput(); + void SetUseCompression( bool useCompression ); + protected: /** * Constructor. */ ImageWriter(); /** * Virtual destructor. */ virtual ~ImageWriter(); virtual void GenerateData(); virtual void WriteByITK(mitk::Image* image, const std::string& fileName); std::string m_FileName; std::string m_FilePrefix; std::string m_FilePattern; std::string m_Extension; std::string m_MimeType; + + bool m_UseCompression; }; } #endif //_MITK_IMAGE_WRITER__H_