00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <qregexp.h>
00019 #include <qmessagebox.h>
00020 #include <qfileinfo.h>
00021 #include <qstring.h>
00022 #include <QDateTime>
00023 #include <string>
00024 #include <strstream>
00025 #include "mitkPointSetWriter.h"
00026 #include "mitkConfig.h"
00027 #include "mitkCoreObjectFactory.h"
00028 #include "QmitkCommonFunctionality.h"
00029 #include <mitkImageAccessByItk.h>
00030 #include <mitkPicFileReader.h>
00031
00032 #include <mitkIpPic.h>
00033
00034 #include <vtkWindowToImageFilter.h>
00035 #include <vtkRenderWindow.h>
00036 #include <vtkPNGWriter.h>
00037 #include <vtkCellArray.h>
00038 #include <vtkTriangleFilter.h>
00039
00040 void CommonFunctionality::SaveToFileWriter( mitk::FileWriterWithInformation::Pointer fileWriter, mitk::BaseData::Pointer data, const char* aFileName, const char* propFileName)
00041 {
00042 if (! fileWriter->CanWriteDataType(data) ) {
00043 QMessageBox::critical(NULL,"ERROR","Could not write file. Invalid data type for file writer.");
00044 return;
00045 }
00046
00047 QString fileName;
00048 if (aFileName == NULL)
00049 {
00050 QString proposedName("");
00051 if(propFileName == NULL)
00052 {
00053 proposedName.append(fileWriter->GetDefaultFilename());
00054 }
00055 else
00056 {
00057 proposedName.append(propFileName).append(fileWriter->GetDefaultExtension());
00058 }
00059 fileName = QFileDialog::getSaveFileName(NULL, "Save file", proposedName,fileWriter->GetFileDialogPattern());
00060
00061
00062 if ( !fileName.contains( QRegExp("\\.\\w+$") ) )
00063 {
00064 fileName.append( fileWriter->GetDefaultExtension() );
00065 }
00066 else
00067 {
00068 std::string extension = itksys::SystemTools::GetFilenameLastExtension( fileName.toLocal8Bit().constData() );
00069 if (!fileWriter->IsExtensionValid(extension))
00070 {
00071 QString message;
00072 message.append("File extension not suitable for writing given data. Choose one extension of this list: ");
00073 message.append(fileWriter->GetPossibleFileExtensionsAsString().c_str());
00074 QMessageBox::critical(NULL,"ERROR",message);
00075 return;
00076 }
00077 }
00078 }
00079 else
00080 fileName = aFileName;
00081
00082 if (fileName.isEmpty() == false )
00083 {
00084 fileWriter->SetFileName( fileName.toLocal8Bit().constData() );
00085 fileWriter->DoWrite( data );
00086 }
00087 }
00088
00089
00097 void CommonFunctionality::SaveBaseData( mitk::BaseData* data, const char * aFileName )
00098 {
00099
00100 QDateTime initialTime = QDateTime::currentDateTime();
00101 std::string fileNameUsed;
00102 bool writingSuccessful = false;
00103
00104 try{
00105 if (data != NULL)
00106 {
00107 mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(data);
00108 QString classname(data->GetNameOfClass());
00109 if(image.IsNotNull() && classname.compare("Image")==0)
00110 {
00111 fileNameUsed = CommonFunctionality::SaveImage(image, aFileName, true);
00112 if(!(fileNameUsed.length()>0)){
00113 return;
00114 } else {
00115 writingSuccessful = true;
00116 }
00117 }
00118
00119 if(!writingSuccessful)
00120 {
00121 mitk::PointSet::Pointer pointset = dynamic_cast<mitk::PointSet*>(data);
00122 if(pointset.IsNotNull())
00123 {
00124 std::string fileName;
00125 if(aFileName == NULL)
00126 fileName = "PointSet";
00127 else
00128 fileName = aFileName;
00129 fileName = itksys::SystemTools::GetFilenameWithoutExtension(fileName);
00130 fileName += ".mps";
00131 QString qfileName = QFileDialog::getSaveFileName(NULL, "Save file", QString(fileName.c_str()),"MITK Point-Sets (*.mps)");
00132 MITK_INFO<<qfileName.toLocal8Bit().constData();
00133
00134 mitk::PointSetWriter::Pointer writer = mitk::PointSetWriter::New();
00135 std::string extension = itksys::SystemTools::GetFilenameLastExtension( qfileName.toLocal8Bit().constData() );
00136
00137 if (!writer->IsExtensionValid(extension))
00138 {
00139 QString message;
00140 message.append("File extension not suitable for writing point set data. Choose one extension of this list: ");
00141 message.append(writer->GetPossibleFileExtensionsAsString().c_str());
00142 QMessageBox::critical(NULL,"ERROR",message);
00143 return;
00144 }
00145
00146 if (fileName.empty() == false )
00147 {
00148 writer->SetInput( pointset );
00149 writer->SetFileName( qfileName.toLocal8Bit().constData() );
00150 writer->Update();
00151 fileNameUsed = writer->GetFileName();
00152 writingSuccessful = true;
00153 } else {
00154 return;
00155 }
00156 }
00157
00158 if(!writingSuccessful)
00159 {
00160 mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface*>(data);
00161 if(surface.IsNotNull())
00162 {
00163 fileNameUsed = CommonFunctionality::SaveSurface(surface, aFileName);
00164 if(!(fileNameUsed.length()>0)){
00165 return;
00166 } else {
00167 writingSuccessful = true;
00168 }
00169 }
00170
00171 if(!writingSuccessful)
00172 {
00173
00174 mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters();
00175 bool writerFound = false;
00176
00177 for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it)
00178 {
00179 if ( (*it)->CanWriteDataType(data) ) {
00180 writerFound = true;
00181 SaveToFileWriter(*it, data, NULL, aFileName);
00182 fileNameUsed = (*it)->GetFileName();
00183
00184 if(!(fileNameUsed.length()>0)){
00185 return;
00186 } else {
00187 writingSuccessful = true;
00188 break;
00189 }
00190 }
00191 }
00192 if(!writerFound)
00193 {
00194
00195 QMessageBox::critical(NULL,"ERROR","Could not find file writer for this data type");
00196 return;
00197 }
00198 }
00199 }
00200
00201 }
00202 } else {
00203 QMessageBox::critical(NULL,"ERROR","Cannot write data (invalid/empty)");
00204 return;
00205 }
00206 } catch(itk::ExceptionObject e)
00207 {
00208 QMessageBox::critical( NULL, "SaveDialog", e.GetDescription(),QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
00209 }
00210
00211
00212
00213
00214 try{
00215 QFileInfo* fileInfo = new QFileInfo(QString(fileNameUsed.c_str()));
00216 if(!fileInfo->exists())
00217 {
00218 QMessageBox::warning(NULL,"WARNING","File was not created or was split into multiple files");
00219 } else if(fileInfo->size()==0) {
00220 QMessageBox::warning(NULL,"WARNING","File is empty");
00221 } else if(fileInfo->lastModified()<initialTime) {
00222 QMessageBox::warning(NULL,"WARNING","Save not successful. File was not updated (only old version available)");
00223 }
00224 delete fileInfo;
00225 } catch(...) {
00226 QMessageBox::critical(NULL,"ERROR","Save not successful. Possibly no writing permission.");
00227 }
00228 }
00229 mitk::DataNode::Pointer CommonFunctionality::FileOpen( const QString& fileName)
00230 {
00231 return FileOpen( fileName.toLocal8Bit().constData() );
00232 }
00233
00234 mitk::DataNode::Pointer CommonFunctionality::FileOpen( const char * fileName )
00235 {
00236 mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
00237
00238 try
00239 {
00240 factory->SetFileName( fileName );
00241 factory->Update();
00242 return factory->GetOutput( 0 );
00243 }
00244 catch ( itk::ExceptionObject & ex )
00245 {
00246 itkGenericOutputMacro( << "Exception during file open: " << ex );
00247 return NULL;
00248 }
00249 }
00250
00251 mitk::DataNode::Pointer CommonFunctionality::FileOpenImageSequence(const QString& aFileName)
00252 {
00253 return FileOpenImageSequence( aFileName.toLocal8Bit().constData() );
00254 }
00255
00256 mitk::DataNode::Pointer CommonFunctionality::FileOpenImageSequence(const char* aFileName)
00257 {
00258 if(aFileName==NULL) return NULL;
00259
00260 mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
00261
00262 QString fileName = aFileName;
00263 if (!fileName.contains("dcm") && !fileName.contains("DCM"))
00264 {
00265 int fnstart = fileName.lastIndexOf( QRegExp("[/\\\\]"), fileName.length() );
00266 if(fnstart<0) fnstart=0;
00267 int start = fileName.indexOf( QRegExp("[0-9]"), fnstart );
00268 if(start<0)
00269 {
00270 return FileOpen(fileName.toLocal8Bit().constData());;
00271 }
00272
00273 char prefix[1024], pattern[1024];
00274
00275 strncpy(prefix, fileName.toLocal8Bit().constData(), start);
00276 prefix[start]=0;
00277
00278 int stop=fileName.indexOf( QRegExp("[^0-9]"), start );
00279 sprintf(pattern, "%%s%%0%uu%s",stop-start,fileName.toLocal8Bit().constData()+stop);
00280
00281
00282 factory->SetFilePattern( pattern );
00283 factory->SetFilePrefix( prefix );
00284 }
00285 else
00286 {
00287
00288 factory->SetFilePattern( fileName.toLocal8Bit().constData() );
00289 factory->SetFilePrefix( fileName.toLocal8Bit().constData() );
00290 }
00291 factory->Update();
00292 return factory->GetOutput( 0 );
00293
00294 }
00295
00296 mitk::DataNode::Pointer CommonFunctionality::FileOpenImageSequence()
00297 {
00298 QString fileName = QFileDialog::getOpenFileName(NULL,mitk::CoreObjectFactory::GetInstance()->GetFileExtensions());
00299
00300 if ( !fileName.isNull() )
00301 {
00302 return FileOpenImageSequence(fileName);
00303 }
00304 else
00305 {
00306 return NULL;
00307 }
00308 }
00309
00310 mitk::DataNode::Pointer CommonFunctionality::FileOpen()
00311 {
00312 return CommonFunctionality::FileOpenSpecific( mitk::CoreObjectFactory::GetInstance()->GetFileExtensions() );
00313 }
00314
00315 mitk::DataNode::Pointer CommonFunctionality::FileOpenSpecific( const QString& fileExtensions)
00316 {
00317 return FileOpenSpecific( fileExtensions.toLocal8Bit().constData() );
00318 }
00319
00320 mitk::DataNode::Pointer CommonFunctionality::FileOpenSpecific( const char *fileExtensions )
00321 {
00322 QString fileName = QFileDialog::getOpenFileName( NULL, fileExtensions );
00323 if ( !fileName.isNull() )
00324 {
00325 mitk::DataNode::Pointer result = FileOpen(fileName.toLocal8Bit().constData());
00326 if ( result.IsNull() )
00327 {
00328 return FileOpenImageSequence(fileName);
00329 }
00330 else
00331 {
00332 return result;
00333 }
00334 }
00335 else
00336 {
00337 return NULL;
00338 }
00339 }
00340
00341 mitk::DataNode::Pointer CommonFunctionality::OpenVolumeOrSliceStack()
00342 {
00343 mitk::DataNode::Pointer newNode = NULL;
00344
00345 QString fileName = QFileDialog::getOpenFileName(NULL,mitk::CoreObjectFactory::GetInstance()->GetFileExtensions() );
00346 if ( !fileName.isNull() )
00347 {
00348 newNode = CommonFunctionality::FileOpen(fileName);
00349 if (newNode.IsNotNull())
00350 {
00351 mitk::Image::Pointer imageData = dynamic_cast<mitk::Image*> (newNode->GetData()) ;
00352 if (imageData.IsNull()) return NULL;
00353
00354 if (imageData->GetDimension(2) == 1)
00355 {
00356
00357 newNode = CommonFunctionality::FileOpenImageSequence(fileName);
00358 imageData = dynamic_cast<mitk::Image*> (newNode->GetData());
00359 }
00360 return newNode;
00361 }
00362 }
00363 {
00364 return NULL;
00365 }
00366 }
00367
00368 #include "mitkSurfaceVtkWriter.h"
00369 #include <vtkSTLWriter.h>
00370 #include <vtkPolyDataWriter.h>
00371 #include <vtkXMLPolyDataWriter.h>
00372
00373 std::string CommonFunctionality::SaveSurface(mitk::Surface* surface, const char* aFileName)
00374 {
00375 std::string fileName;
00376 if(aFileName == NULL)
00377 fileName = "Surface";
00378 else
00379 fileName = aFileName;
00380
00381 std::string selectedItemsName = itksys::SystemTools::GetFilenameWithoutExtension(fileName);
00382 selectedItemsName += ".stl";
00383 QString qfileName = QFileDialog::getSaveFileName(NULL, "Save surface object", QString(selectedItemsName.c_str()),"Surface Data(*.stl *.vtk *.vtp)");
00384 if (!(qfileName.isEmpty()) )
00385 {
00386 if(qfileName.endsWith(".stl")==true)
00387 {
00388 mitk::SurfaceVtkWriter<vtkSTLWriter>::Pointer writer=mitk::SurfaceVtkWriter<vtkSTLWriter>::New();
00389
00390
00391 vtkPolyData* polys = surface->GetVtkPolyData();
00392 if( polys->GetNumberOfStrips() > 0 )
00393 {
00394 vtkTriangleFilter* triangleFilter = vtkTriangleFilter::New();
00395 triangleFilter->SetInput(polys);
00396 triangleFilter->Update();
00397 polys = triangleFilter->GetOutput();
00398 polys->Register(NULL);
00399 triangleFilter->Delete();
00400 surface->SetVtkPolyData(polys);
00401 }
00402
00403 writer->SetInput( surface );
00404 writer->SetFileName(qfileName.toLocal8Bit().constData());
00405 writer->GetVtkWriter()->SetFileTypeToBinary();
00406 writer->Write();
00407 }
00408 else
00409 if(qfileName.endsWith(".vtp")==true)
00410 {
00411 mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::Pointer writer=mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::New();
00412 writer->SetInput( surface );
00413 writer->SetFileName(qfileName.toLocal8Bit().constData());
00414 writer->GetVtkWriter()->SetDataModeToBinary();
00415 writer->Write();
00416 }
00417 else if (qfileName.endsWith(".vtk")==true)
00418 {
00419
00420
00421 mitk::SurfaceVtkWriter<vtkPolyDataWriter>::Pointer writer=mitk::SurfaceVtkWriter<vtkPolyDataWriter>::New();
00422 writer->SetInput( surface );
00423 writer->SetFileName(qfileName.toLocal8Bit().constData());
00424 writer->Write();
00425 }
00426 else
00427 {
00428
00429 QMessageBox::critical(NULL,"ERROR","File extension not suitable for writing Surface data. Choose .vtk, .stl or .vtp");
00430 return "";
00431 }
00432 fileName = qfileName.toLocal8Bit().constData();
00433 }
00434 else
00435 {
00436 fileName.clear();
00437 }
00438 return fileName;
00439 }
00440
00441 #include "mitkImageWriter.h"
00442 #include <itksys/SystemTools.hxx>
00443
00444 std::string CommonFunctionality::SaveImage(mitk::Image* image, const char* aFileName, bool askForDifferentFilename)
00445 {
00446 static QString lastDirectory = "";
00447
00448 std::string fileName;
00449 if(aFileName == NULL || askForDifferentFilename)
00450 {
00451 QString initialFilename(aFileName);
00452 if (initialFilename.isEmpty()) initialFilename = "NewImage.pic";
00453
00454
00455 initialFilename = lastDirectory + initialFilename;
00456
00457 QString suffix_pic("DKFZ Pic (*.pic)");
00458 QString qfileName = QFileDialog::getSaveFileName( NULL, "Save image", initialFilename ,mitk::CoreObjectFactory::GetInstance()->GetSaveFileExtensions(),&suffix_pic);
00459 MITK_INFO<<qfileName.toLocal8Bit().constData();
00460 if (qfileName.isEmpty() )
00461 return "";
00462 fileName = qfileName.toLocal8Bit().constData();
00463 }
00464 else
00465 fileName = aFileName;
00466
00467 try
00468 {
00469 std::string dir = itksys::SystemTools::GetFilenamePath( fileName );
00470 std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( fileName );
00471 std::string extension = itksys::SystemTools::GetFilenameLastExtension( fileName );
00472
00473 if (extension == "")
00474 extension = ".pic";
00475
00476 if (extension == ".gz")
00477 {
00478 QMessageBox::critical( NULL, "SaveDialog", "Warning: You can not save an image in the compressed \n"
00479 ".pic.gz format. You must save as a normal .pic file.\n"
00480 "Please press Save again and choose a filename with a .pic ending.",
00481 QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
00482 return "";
00483 }
00484
00485 mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New();
00486 if (!imageWriter->IsExtensionValid(extension))
00487 {
00488 QString message;
00489 message.append("File extension not suitable for writing image data. Choose one extension of this list: ");
00490 message.append(imageWriter->GetPossibleFileExtensionsAsString().c_str());
00491 QMessageBox::critical(NULL,"ERROR",message);
00492 return "";
00493 }
00494 dir += "/";
00495 lastDirectory = dir.c_str();
00496 dir += baseFilename;
00497
00498 imageWriter->SetInput(image);
00499 imageWriter->SetFileName(dir.c_str());
00500 imageWriter->SetExtension(extension.c_str());
00501 imageWriter->Write();
00502 }
00503 catch ( itk::ExceptionObject &err)
00504 {
00505 itkGenericOutputMacro( << "Exception during write: " << err );
00506 QString exceptionString;
00507 exceptionString.append("Error during write image: ");
00508 exceptionString.append(err.GetDescription());
00509 QMessageBox::critical(NULL,"ERROR",exceptionString);
00510 return "";
00511 }
00512 catch ( ... )
00513 {
00514 itkGenericOutputMacro( << "Unknown type of exception during write" );
00515 QMessageBox::critical(NULL,"ERROR","Error during write image. Possibly no writing permission.");
00516 fileName = "";
00517 }
00518 return fileName;
00519 }
00520
00521
00522 std::string CommonFunctionality::SaveScreenshot( vtkRenderWindow* renderWindow , const char* filename )
00523 {
00524
00525
00526
00527 if ( ! renderWindow )
00528 {
00529 itkGenericOutputMacro( << "render window is NULL!" );
00530 return std::string("");
00531 }
00532 if ( ! renderWindow )
00533 {
00534 itkGenericOutputMacro( << "Unsupported type of render window! The only supported type is currently QmitkRenderWindow." );
00535 return std::string("");
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00546 vtkWindowToImageFilter* wti = vtkWindowToImageFilter::New();
00547 wti->SetInput( renderWindow );
00548 wti->Update();
00549 vtkImageData* imageData = wti->GetOutput();
00550 int framesize = 5;
00551 int* windowSize = renderWindow->GetSize();
00552 int numberOfScalarComponents = imageData->GetNumberOfScalarComponents();
00553 vtkImageData* processedImageData = vtkImageData::New();
00554 processedImageData->SetNumberOfScalarComponents(numberOfScalarComponents);
00555 processedImageData->SetExtent(0,windowSize[0]-2*framesize-1,0,windowSize[1]-2*framesize-1,0,0);
00556 processedImageData->SetScalarTypeToUnsignedChar();
00557 for (int i=framesize; i<windowSize[0]-framesize; i++)
00558 {
00559 for (int j=framesize; j<windowSize[1]-framesize; j++)
00560 {
00561 for (int k=0; k<numberOfScalarComponents; k++)
00562 {
00563 processedImageData->SetScalarComponentFromDouble(i-framesize,j-framesize,0,k,imageData->GetScalarComponentAsDouble(i,j,0,k));
00564 }
00565 }
00566 }
00567
00568
00569 vtkPNGWriter* pngWriter = vtkPNGWriter::New();
00570
00571
00572
00573
00574
00575
00576 std::string concreteFilename = "";
00577 if( filename == NULL )
00578 {
00579
00580
00581
00582 QString qfileName = QFileDialog::getSaveFileName( NULL, "Save screenshot", QString( "" ), QString( ".png" ).toLocal8Bit().constData() );
00583 if ( qfileName.isEmpty() )
00584 return "";
00585 concreteFilename = qfileName.toLocal8Bit().constData();
00586 }
00587 else
00588 concreteFilename = filename;
00589
00590
00591 const std::string outFileSuffix("png");
00592 std::string::size_type pos = concreteFilename.rfind('.');
00593
00594 if ( pos == std::string::npos )
00595 concreteFilename = concreteFilename + '.' + outFileSuffix;
00596 else
00597 {
00598 std::string extname = concreteFilename.substr(pos+1);
00599 if ( extname.empty() ) concreteFilename += outFileSuffix;
00600 if ( !(extname == outFileSuffix) )
00601 concreteFilename.replace( pos+1, std::string::npos, "png" );
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 pngWriter->SetInput(processedImageData);
00618
00619 pngWriter->SetFileName( concreteFilename.c_str() );
00620
00621 pngWriter->Write();
00622
00623 if ( pngWriter->GetErrorCode() != 0 )
00624 QMessageBox::information(NULL, "Save Screenshot...", "The file could not be saved. Please check filename, format and access rights...");
00625
00626 wti->Delete();
00627 pngWriter->Delete();
00628 return concreteFilename;
00629 }
00630