New export logic(with out annotation)
This commit is contained in:
@@ -1,7 +1,17 @@
|
|||||||
#include "dicomexporter.h"
|
#include "dicomexporter.h"
|
||||||
#include "Common/SeriesImageSet.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
#include "IO/DICOM/DICOMPixelDataHelper.h"
|
||||||
|
#include "IO/Convert/DICOMToQImageConverter.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const char* FileExtention[3]={
|
||||||
|
"bmp","jpg","png"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
DicomExporter::DicomExporter(QObject *parent)
|
DicomExporter::DicomExporter(QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
exportedNumber(0)
|
exportedNumber(0)
|
||||||
@@ -19,477 +29,101 @@ void DicomExporter::execute(ExportOptions options)
|
|||||||
return;// to avoid exception
|
return;// to avoid exception
|
||||||
}
|
}
|
||||||
|
|
||||||
initVTK();
|
|
||||||
exportedNumber = 0;
|
exportedNumber = 0;
|
||||||
totalCount = 0;
|
totalCount = 0;
|
||||||
|
|
||||||
caculateExportTotalCount();//caculate the total count of file to be exported
|
caculateExportTotalCount();//caculate the total count of file to be exported
|
||||||
|
if (exportOptions.slice >= 0){
|
||||||
if (exportOptions.exportFileFormat == ExportOptions::FileFormat::Dicom)
|
if (exportOptions.inputData.empty()
|
||||||
{
|
|| exportOptions.inputData[0]->GetFileNames().empty()) {
|
||||||
for (int i = 0; i < exportOptions.inputData.size(); i++)
|
emit exportError();
|
||||||
{
|
return;
|
||||||
//Note<74><65>When the smart pointer points to another variable, it is automatically
|
}
|
||||||
//released, you can move it to outside or not.
|
std::string fileName = exportOptions.inputData[0]->GetFileNames()[exportOptions.slice].first;
|
||||||
initDataReader();
|
long frame = exportOptions.inputData[0]->GetFileNames()[exportOptions.slice].second;
|
||||||
exportDicom(exportOptions.inputData.at(i));
|
DICOMToQImageConverter convert;
|
||||||
}
|
if (frame>=0){
|
||||||
|
convert.setFrame(frame);
|
||||||
|
}
|
||||||
|
convert.setInputDICOMFile(fileName.c_str());
|
||||||
|
convert.setWindow(exportOptions.windowLevel, exportOptions.windowWidth);
|
||||||
|
if (exportOptions.inputData[0]->GetSamplePerPixel()>1)
|
||||||
|
{
|
||||||
|
convert.setColorImage(exportOptions.inputData[0]->GetSamplePerPixel());
|
||||||
|
}
|
||||||
|
convert.save();
|
||||||
|
auto img = convert.getQImage();
|
||||||
|
bool ret = img->save(QString("%1/%2%3.%4")
|
||||||
|
.arg(exportOptions.exportDirectory,exportOptions.fileNamePrefix)
|
||||||
|
.arg(0).arg(getFileExtention()),getFileExtention());
|
||||||
|
delete img;
|
||||||
|
if(ret){
|
||||||
|
emit exportFinished();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
emit exportError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
{
|
long successCount = 0;
|
||||||
for (int i = 0; i < exportOptions.inputData.size(); i++)
|
long processCount = 0;
|
||||||
{
|
DICOMPixelDataHelper::InitCodecs();
|
||||||
initDataReader();
|
for (int i = 0; i < exportOptions.inputData.size(); ++i) {
|
||||||
exportPicture(exportOptions.inputData.at(i));
|
auto property = exportOptions.inputData[i];
|
||||||
}
|
if (property->GetFileNames().empty())continue;
|
||||||
|
QString savedir = QString("%1/%2").arg(exportOptions.exportDirectory,property->GetSeriesUID());
|
||||||
|
dir.mkpath(savedir);
|
||||||
|
for (int j = 0; j < property->GetFileNames().size(); ++j) {
|
||||||
|
std::string fileName = property->GetFileNames()[j].first;
|
||||||
|
long frame = property->GetFileNames()[j].second;
|
||||||
|
DICOMToQImageConverter convert;
|
||||||
|
if (frame>=0){
|
||||||
|
convert.setFrame(frame);
|
||||||
|
}
|
||||||
|
convert.setInputDICOMFile(fileName.c_str());
|
||||||
|
double * window = property->GetNthWindowLevelPreset(0);
|
||||||
|
convert.setWindow(window[1], window[0]);
|
||||||
|
if (property->GetSamplePerPixel()>1)
|
||||||
|
{
|
||||||
|
convert.setColorImage(property->GetSamplePerPixel());
|
||||||
|
}
|
||||||
|
convert.save();
|
||||||
|
auto img = convert.getQImage();
|
||||||
|
bool ret = img->save(QString("%1/%2%3.%4")
|
||||||
|
.arg(savedir,exportOptions.fileNamePrefix)
|
||||||
|
.arg(j).arg(getFileExtention()),getFileExtention());
|
||||||
|
delete img;
|
||||||
|
if (ret)++successCount;
|
||||||
|
++processCount;
|
||||||
|
emit exportProgress(totalCount,processCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
DICOMPixelDataHelper::FinalizeCodecs();
|
||||||
|
DICOMPixelDataHelper::ClearFileObjectCache();
|
||||||
|
if(totalCount == successCount){
|
||||||
|
emit exportFinished();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
emit exportError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit exportFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char * DicomExporter::getFileExtention()
|
||||||
void DicomExporter::initVTK()
|
|
||||||
{
|
{
|
||||||
m_glrenWinExport = vtkSmartPointer<vtkRenderWindow>::New();
|
return FileExtention[exportOptions.exportFileFormat];
|
||||||
m_glrenWinExport->OffScreenRenderingOn();
|
|
||||||
|
|
||||||
m_imageViewerExport = vtkSmartPointer<DICOMImageViewer>::New();
|
|
||||||
m_imageViewerExport->SetRenderWindow(m_glrenWinExport);
|
|
||||||
m_imageViewerExport->SetupInteractor(m_glrenWinExport->GetInteractor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DicomExporter::initDataReader()
|
|
||||||
{
|
|
||||||
// m_gdcmIOExport = ImageIOTypeExport::New();
|
|
||||||
// m_itkSeriesReaderExport = SeriesReaderTypeExport::New();
|
|
||||||
// m_itkSeriesReaderExport->SetImageIO(m_gdcmIOExport);
|
|
||||||
// m_itkConnectorExport = ConnectorTypeExport::New();
|
|
||||||
// m_inputNamesExport = InputNamesGeneratorTypeExport::New();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DicomExporter::loadDicomFileAndRender(int file_type)
|
|
||||||
{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// m_itkSeriesReaderExport->Update();
|
|
||||||
// }
|
|
||||||
// catch (itk::ExceptionObject &excp) {
|
|
||||||
// std::cerr << "Exception thrown while reading the series" << std::endl;
|
|
||||||
// std::cerr << excp << std::endl;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// m_itkConnectorExport->SetInput(m_itkSeriesReaderExport->GetOutput());
|
|
||||||
// m_itkConnectorExport->Update();
|
|
||||||
//
|
|
||||||
// m_imageViewerExport->SetInputData(m_itkConnectorExport->GetOutput());
|
|
||||||
//
|
|
||||||
// m_imageViewerExport->Render();
|
|
||||||
// m_imageViewerExport->SetSlice(0);
|
|
||||||
//
|
|
||||||
// //m_imageViewerExport->GetRenderer()->ResetCamera();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// infinitiViewer *viewer = exportOptions.serie->getImageViewer2();
|
|
||||||
//
|
|
||||||
// if (exportOptions.windowLevel != -1)
|
|
||||||
// {
|
|
||||||
// m_imageViewerExport->SetColorLevel(exportOptions.windowLevel);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (exportOptions.windowWidth != -1)
|
|
||||||
// {
|
|
||||||
// m_imageViewerExport->SetColorWindow(exportOptions.windowWidth);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (exportOptions.cornerAnnotation != ExportOptions::CornerAnnotation::Disabled)
|
|
||||||
// {
|
|
||||||
// if (AnnoHelper::IsAnno()) {
|
|
||||||
// vtkCornerAnnotation* ann = m_imageViewerExport->GetvtkCornerAnnotation();
|
|
||||||
// ann->SetMaximumFontSize(20);
|
|
||||||
// ann->CopyAllTextsFrom(viewer->GetvtkCornerAnnotation());
|
|
||||||
// ann->SetText(BOTTOM_LEFT, "");
|
|
||||||
//
|
|
||||||
// std::string lbl_ser_num;
|
|
||||||
// std::string ser_num;
|
|
||||||
// itk::GDCMImageIO::GetLabelFromTag(USER_CONFIG::TAG_SERIES_NUMBER, lbl_ser_num);
|
|
||||||
// m_gdcmIOExport->GetValueFromTag(USER_CONFIG::TAG_SERIES_NUMBER, ser_num);
|
|
||||||
// m_imageViewerExport->initTopLeftCornerInfo(lbl_ser_num, ser_num);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// double vup[3];
|
|
||||||
// double vup2[3];
|
|
||||||
// vtkCamera *oriCamera = viewer->GetRenderer()->GetActiveCamera();
|
|
||||||
// double scale = exportOptions.serie->GetExtent();
|
|
||||||
// oriCamera->GetViewUp(vup);
|
|
||||||
//
|
|
||||||
// vtkCamera *expCamera = m_imageViewerExport->GetRenderer()->GetActiveCamera();
|
|
||||||
// expCamera->SetParallelScale(scale);
|
|
||||||
// expCamera->GetViewUp(vup2);
|
|
||||||
// expCamera->SetViewUp(vup);
|
|
||||||
//
|
|
||||||
// if (FlipExportHelper::GetFlip())
|
|
||||||
// {
|
|
||||||
// expCamera->Azimuth(180);
|
|
||||||
// m_imageViewerExport->GetRenderer()->ResetCameraClippingRange();
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// m_imageViewerExport->GetRenderWindow()->Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DicomExporter::doExport(int file_type)
|
|
||||||
{
|
|
||||||
if (file_type == SingleFile)
|
|
||||||
{
|
|
||||||
exportedNumber++;//image number starts from 1
|
|
||||||
QString fileName = exportOptions.exportDirectory + "/" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + getFileExtention();
|
|
||||||
writeToFile(fileName);
|
|
||||||
emit exportProgress(totalCount, exportedNumber);
|
|
||||||
}
|
|
||||||
else if(file_type == DirType)
|
|
||||||
{
|
|
||||||
int m_MinSliceExport = m_imageViewerExport->GetSliceMin();
|
|
||||||
int m_MaxSliceExport = m_imageViewerExport->GetSliceMax();
|
|
||||||
|
|
||||||
for (int i = m_MinSliceExport; i <= m_MaxSliceExport; i++)
|
|
||||||
{
|
|
||||||
m_imageViewerExport->SetSlice(i);
|
|
||||||
//m_imageViewerExport->Render();
|
|
||||||
|
|
||||||
exportedNumber++;//image number starts from 1
|
|
||||||
QString fileName = exportOptions.exportDirectory + "/" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + getFileExtention();
|
|
||||||
writeToFile(fileName);
|
|
||||||
|
|
||||||
emit exportProgress(totalCount, exportedNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DicomExporter::writeToFile(const QString& fileName)
|
|
||||||
{
|
|
||||||
// Screenshot
|
|
||||||
vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
|
|
||||||
|
|
||||||
windowToImageFilter->SetInput(m_glrenWinExport);
|
|
||||||
#if VTK_MAJOR_VERSION >= 8 || VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 90
|
|
||||||
windowToImageFilter->SetScale(2); // image quality
|
|
||||||
#else
|
|
||||||
windowToImageFilter->SetMagnification(2); //image quality
|
|
||||||
#endif
|
|
||||||
|
|
||||||
windowToImageFilter->Update();
|
|
||||||
|
|
||||||
|
|
||||||
switch (exportOptions.exportFileFormat)
|
|
||||||
{
|
|
||||||
case ExportOptions::FileFormat::Bmp:
|
|
||||||
writeToBmpFile(windowToImageFilter, fileName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportOptions::FileFormat::Jpeg:
|
|
||||||
writeToJpgFile(windowToImageFilter, fileName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportOptions::FileFormat::Png:
|
|
||||||
writeToPngFile(windowToImageFilter, fileName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportOptions::FileFormat::Tiff:
|
|
||||||
writeToTiffFile(windowToImageFilter, fileName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DicomExporter::getFileExtention()
|
|
||||||
{
|
|
||||||
QString fileExtention = ".png";
|
|
||||||
|
|
||||||
switch (exportOptions.exportFileFormat)
|
|
||||||
{
|
|
||||||
case ExportOptions::FileFormat::Bmp:
|
|
||||||
fileExtention = ".bmp";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportOptions::FileFormat::Jpeg:
|
|
||||||
fileExtention = ".jpg";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportOptions::FileFormat::Png:
|
|
||||||
fileExtention = ".png";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportOptions::FileFormat::Tiff:
|
|
||||||
fileExtention = ".tiff";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportOptions::FileFormat::Dicom:
|
|
||||||
fileExtention = ".dcm";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileExtention;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::writeToPngFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName)
|
|
||||||
{
|
|
||||||
QByteArray bafileName = fileName.toLocal8Bit();
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New();
|
|
||||||
writer->SetFileName(bafileName.data());
|
|
||||||
writer->SetInputConnection(windowToImageFilter->GetOutputPort());
|
|
||||||
writer->Write();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::writeToBmpFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName)
|
|
||||||
{
|
|
||||||
QByteArray bafileName = fileName.toLocal8Bit();
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkBMPWriter> writer = vtkSmartPointer<vtkBMPWriter>::New();
|
|
||||||
writer->SetFileName(bafileName.data());
|
|
||||||
writer->SetInputConnection(windowToImageFilter->GetOutputPort());
|
|
||||||
writer->Write();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::writeToJpgFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName)
|
|
||||||
{
|
|
||||||
QByteArray bafileName = fileName.toLocal8Bit();
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkJPEGWriter> writer = vtkSmartPointer<vtkJPEGWriter>::New();
|
|
||||||
writer->SetFileName(bafileName.data());
|
|
||||||
writer->SetInputConnection(windowToImageFilter->GetOutputPort());
|
|
||||||
writer->Write();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::writeToTiffFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName)
|
|
||||||
{
|
|
||||||
QByteArray bafileName = fileName.toLocal8Bit();
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkTIFFWriter> writer = vtkSmartPointer<vtkTIFFWriter>::New();
|
|
||||||
writer->SetFileName(bafileName.data());
|
|
||||||
writer->SetInputConnection(windowToImageFilter->GetOutputPort());
|
|
||||||
writer->Write();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::exportPicture(const QString& fileName)
|
|
||||||
{
|
|
||||||
// int myFileType = NonType;
|
|
||||||
//
|
|
||||||
// QFileInfo fileInfo(fileName);
|
|
||||||
// QDir dir(fileName);
|
|
||||||
//
|
|
||||||
// if (fileInfo.isFile())
|
|
||||||
// {
|
|
||||||
// m_itkSeriesReaderExport->SetFileName(fileName.toStdString());
|
|
||||||
//
|
|
||||||
// myFileType = SingleFile;
|
|
||||||
// }
|
|
||||||
// else if (dir.exists())
|
|
||||||
// {
|
|
||||||
// m_inputNamesExport->SetInputDirectory(fileName.toStdString());
|
|
||||||
// const SeriesReaderTypeExport::FileNamesContainer & filenames = m_inputNamesExport->GetInputFileNames();
|
|
||||||
// m_itkSeriesReaderExport->SetFileNames(filenames);
|
|
||||||
//
|
|
||||||
// myFileType = DirType;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (myFileType != NonType)
|
|
||||||
// {
|
|
||||||
// loadDicomFileAndRender(myFileType);
|
|
||||||
// doExport(myFileType);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::exportDicom(const QString& fileName)
|
|
||||||
{
|
|
||||||
// bool isFileValid = false;
|
|
||||||
//
|
|
||||||
// QFileInfo fileInfo(fileName);
|
|
||||||
// QDir dir(fileName);
|
|
||||||
//
|
|
||||||
// if (fileInfo.isFile())
|
|
||||||
// {
|
|
||||||
// m_itkSeriesReaderExport->SetFileName(fileName.toStdString());
|
|
||||||
//
|
|
||||||
// exportSingleDicomFile(fileName);
|
|
||||||
// }
|
|
||||||
// else if (dir.exists())
|
|
||||||
// {
|
|
||||||
// m_inputNamesExport->SetInputDirectory(fileName.toStdString());
|
|
||||||
// const SeriesReaderTypeExport::FileNamesContainer & filenames = m_inputNamesExport->GetInputFileNames();
|
|
||||||
// m_itkSeriesReaderExport->SetFileNames(filenames);
|
|
||||||
//
|
|
||||||
// exportDicomDirectory(fileName);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::exportSingleDicomFile(const QString& fileName)
|
|
||||||
{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// m_itkSeriesReaderExport->UpdateLargestPossibleRegion();
|
|
||||||
// m_itkSeriesReaderExport->Update();
|
|
||||||
// }
|
|
||||||
// catch (itk::ExceptionObject &excp) {
|
|
||||||
// std::cerr << "Exception thrown while reading the series" << std::endl;
|
|
||||||
// std::cerr << excp << std::endl;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// exportedNumber++;//image number starts from 1
|
|
||||||
// QString exportedName = exportOptions.exportDirectory + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm";
|
|
||||||
// QByteArray bafileName = exportedName.toLocal8Bit();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
|
|
||||||
// seriesWriter->SetImageIO(m_gdcmIOExport);
|
|
||||||
// seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput());
|
|
||||||
// seriesWriter->SetFileName(std::string(bafileName));
|
|
||||||
//
|
|
||||||
// SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray();
|
|
||||||
// modifyDicomTags(dicArray);
|
|
||||||
// seriesWriter->SetMetaDataDictionaryArray(dicArray);
|
|
||||||
//
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// seriesWriter->Update();
|
|
||||||
//
|
|
||||||
// emit exportProgress(totalCount, exportedNumber);
|
|
||||||
// }
|
|
||||||
// catch (itk::ExceptionObject & excp)
|
|
||||||
// {
|
|
||||||
// std::cerr << "Exception thrown while writing the series " << std::endl;
|
|
||||||
// std::cerr << excp << std::endl;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void DicomExporter::exportDicomDirectory(const QString& fileName)
|
|
||||||
{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// m_itkSeriesReaderExport->Update();
|
|
||||||
// }
|
|
||||||
// catch (itk::ExceptionObject &excp) {
|
|
||||||
// std::cerr << "Exception thrown while reading the series" << std::endl;
|
|
||||||
// std::cerr << excp << std::endl;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// m_inputNamesExport->SetOutputDirectory(exportOptions.exportDirectory.toStdString());
|
|
||||||
//
|
|
||||||
// itk::SerieUIDContainer newOutNames;
|
|
||||||
// itk::SerieUIDContainer oldOutputNames = m_inputNamesExport->GetOutputFileNames();
|
|
||||||
// for (int i = 0; i < oldOutputNames.size(); i++)
|
|
||||||
// {
|
|
||||||
// std::string originName = oldOutputNames.at(i);
|
|
||||||
// QFileInfo fileinfo(QString::fromStdString(originName));
|
|
||||||
// QString fName = fileinfo.fileName();
|
|
||||||
// QString fPath = fileinfo.absolutePath();
|
|
||||||
//
|
|
||||||
// exportedNumber++;//image number starts from 1
|
|
||||||
// QString newName = fPath + "\\" + exportOptions.fileNamePrefix + QString::number(exportedNumber) + ".dcm";
|
|
||||||
// QByteArray bafileName = newName.toLocal8Bit();
|
|
||||||
//
|
|
||||||
// newOutNames.push_back(std::string(bafileName));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
|
|
||||||
// seriesWriter->SetImageIO(m_gdcmIOExport);
|
|
||||||
// seriesWriter->SetInput(m_itkSeriesReaderExport->GetOutput());
|
|
||||||
// seriesWriter->SetFileNames(newOutNames);
|
|
||||||
//
|
|
||||||
// SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray = m_itkSeriesReaderExport->GetMetaDataDictionaryArray();
|
|
||||||
// modifyDicomTags(dicArray);
|
|
||||||
// seriesWriter->SetMetaDataDictionaryArray(dicArray);
|
|
||||||
//
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// emit exportProgress(totalCount, exportedNumber / 2);
|
|
||||||
//
|
|
||||||
// seriesWriter->Update();
|
|
||||||
//
|
|
||||||
// emit exportProgress(totalCount, exportedNumber);
|
|
||||||
// }
|
|
||||||
// catch (itk::ExceptionObject & excp)
|
|
||||||
// {
|
|
||||||
// std::cerr << "Exception thrown while writing the series " << std::endl;
|
|
||||||
// std::cerr << excp << std::endl;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
//void DicomExporter::modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray)
|
|
||||||
//{
|
|
||||||
// for (int i = 0; i < (*dicArray).size(); i++)
|
|
||||||
// {
|
|
||||||
// itk::MetaDataDictionary *dic = (*dicArray).at(i);
|
|
||||||
//
|
|
||||||
// if (exportOptions.windowLevel != -1)
|
|
||||||
// {
|
|
||||||
// std::string entryId(TAG_WindowLevel);
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowLevel));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (exportOptions.windowWidth != -1)
|
|
||||||
// {
|
|
||||||
// std::string entryId(TAG_WindowWidth);
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, entryId, std::to_string(exportOptions.windowWidth));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (exportOptions.isAnonymization)
|
|
||||||
// {
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionName, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_InstitutionAddress, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_ReferringPhysicianName, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OperatorsName, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAddress, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientTelephoneNumbers, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientNames, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDs, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_OtherPatientIDsSequence, "");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientName, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientBirthDate, "19000101");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientSex, "NA");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientAge, "NA");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_PatientID, "anonymized");
|
|
||||||
// itk::EncapsulateMetaData<std::string>(*dic, TAG_AccessionNumber, "anonymized");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }//for end
|
|
||||||
//}
|
|
||||||
|
|
||||||
void DicomExporter::caculateExportTotalCount()
|
void DicomExporter::caculateExportTotalCount()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < exportOptions.inputData.size(); i++)
|
for (int i = 0; i < exportOptions.inputData.size(); i++)
|
||||||
{
|
{
|
||||||
QString fileName = exportOptions.inputData.at(i);
|
auto property = exportOptions.inputData.at(i);
|
||||||
|
totalCount+= property->GetFileNames().size();
|
||||||
QFileInfo fileInfo(fileName);
|
|
||||||
QDir dir(fileName);
|
|
||||||
|
|
||||||
if (fileInfo.isFile())
|
|
||||||
{
|
|
||||||
totalCount++;
|
|
||||||
}
|
|
||||||
else if (dir.exists())
|
|
||||||
{
|
|
||||||
QStringList filter;
|
|
||||||
QFileInfoList fileList = dir.entryInfoList(filter);
|
|
||||||
totalCount += fileList.count();
|
|
||||||
totalCount -= 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,6 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "exportoptions.h"
|
#include "exportoptions.h"
|
||||||
//#include <itkImage.h>
|
|
||||||
//#include <itkGDCMImageIO.h>
|
|
||||||
//#include <itkImageSeriesReader.h>
|
|
||||||
//#include <itkImageSeriesWriter.h>
|
|
||||||
//#include <itkImageToVTKImageFilter.h>
|
|
||||||
//#include <itkGDCMSeriesFileNames.h>
|
|
||||||
#include <vtkRenderer.h>
|
#include <vtkRenderer.h>
|
||||||
#include <vtkSmartPointer.h>
|
#include <vtkSmartPointer.h>
|
||||||
#include <vtkRenderWindow.h>
|
#include <vtkRenderWindow.h>
|
||||||
@@ -24,8 +18,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "Rendering/Viewer/DICOMImageViewer.h"
|
#include "Rendering/Viewer/DICOMImageViewer.h"
|
||||||
//#include "itkMetaDataObject.h"
|
|
||||||
//#include "itkMetaDataDictionary.h"
|
|
||||||
|
|
||||||
|
|
||||||
class DicomExporter : public QObject
|
class DicomExporter : public QObject
|
||||||
@@ -45,79 +37,18 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void exportFinished();
|
void exportFinished();
|
||||||
|
void exportError();
|
||||||
void exportProgress(int total, int progress);
|
void exportProgress(int total, int progress);
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//dicom tags
|
const char* getFileExtention();
|
||||||
const std::string TAG_WindowLevel = "0028|1050";
|
|
||||||
const std::string TAG_WindowWidth = "0028|1051";
|
|
||||||
|
|
||||||
//anonymization
|
|
||||||
const std::string TAG_InstitutionName = "0008|0080";
|
|
||||||
const std::string TAG_InstitutionAddress = "0008|0081";
|
|
||||||
const std::string TAG_ReferringPhysicianName = "0008|0090";
|
|
||||||
const std::string TAG_OperatorsName = "0008|1070";
|
|
||||||
const std::string TAG_PatientAddress = "0010|1040";
|
|
||||||
const std::string TAG_PatientTelephoneNumbers = "0010|2154";
|
|
||||||
const std::string TAG_OtherPatientNames = "0010|1001";
|
|
||||||
const std::string TAG_OtherPatientIDs = "0010|1000";
|
|
||||||
const std::string TAG_OtherPatientIDsSequence = "0010|1002";
|
|
||||||
const std::string TAG_PatientName = "0010|0010";
|
|
||||||
const std::string TAG_PatientBirthDate = "0010|0030";
|
|
||||||
const std::string TAG_PatientSex = "0010|0040";
|
|
||||||
const std::string TAG_PatientAge = "0010|1010";
|
|
||||||
const std::string TAG_PatientID = "0010|0020";
|
|
||||||
const std::string TAG_AccessionNumber = "0008|0050";
|
|
||||||
|
|
||||||
//bmp jpg png tiff exprt releated objects
|
|
||||||
static const unsigned int InputDimensionExport = 3;
|
|
||||||
typedef signed short PixelTypeExport;
|
|
||||||
// typedef itk::Image<PixelTypeExport, InputDimensionExport> InputImageTypeExport;
|
|
||||||
// typedef itk::GDCMImageIO ImageIOTypeExport;
|
|
||||||
// typedef itk::ImageSeriesReader<InputImageTypeExport> SeriesReaderTypeExport;
|
|
||||||
// typedef itk::ImageToVTKImageFilter<InputImageTypeExport> ConnectorTypeExport;
|
|
||||||
// typedef itk::GDCMSeriesFileNames InputNamesGeneratorTypeExport;
|
|
||||||
|
|
||||||
//dicom export releated objects
|
|
||||||
typedef signed short OutputPixelType;
|
|
||||||
static const unsigned int OutputDimension = 2;
|
|
||||||
// typedef itk::Image<OutputPixelType, OutputDimension> Image2DType;
|
|
||||||
// typedef itk::ImageSeriesWriter<InputImageTypeExport, Image2DType> SeriesWriterType;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initVTK();
|
|
||||||
void initDataReader();
|
|
||||||
void loadDicomFileAndRender(int file_type);
|
|
||||||
//void updateCornerInfo(int slice, int maxslice);
|
|
||||||
void doExport(int file_type);
|
|
||||||
QString getFileExtention();
|
|
||||||
void writeToFile(const QString& fileName);
|
|
||||||
void writeToPngFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName);
|
|
||||||
void writeToBmpFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName);
|
|
||||||
void writeToJpgFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName);
|
|
||||||
void writeToTiffFile(vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter, const QString& fileName);
|
|
||||||
void exportPicture(const QString& fileName);
|
|
||||||
void exportDicom(const QString& fileName);
|
|
||||||
void exportSingleDicomFile(const QString& fileName);
|
|
||||||
void exportDicomDirectory(const QString& fileName);
|
|
||||||
// void modifyDicomTags(SeriesReaderTypeExport::DictionaryArrayRawPointer dicArray);
|
|
||||||
void caculateExportTotalCount();
|
void caculateExportTotalCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ExportOptions exportOptions;
|
ExportOptions exportOptions;
|
||||||
int totalCount;//the total count of image to be exported
|
int totalCount;//the total count of image to be exported
|
||||||
int exportedNumber;//the exported image index
|
int exportedNumber;//the exported image index
|
||||||
|
|
||||||
//itk vtk releated objects
|
|
||||||
// ImageIOTypeExport::Pointer m_gdcmIOExport;
|
|
||||||
// SeriesReaderTypeExport::Pointer m_itkSeriesReaderExport;
|
|
||||||
// ConnectorTypeExport::Pointer m_itkConnectorExport;
|
|
||||||
// InputNamesGeneratorTypeExport::Pointer m_inputNamesExport;
|
|
||||||
vtkSmartPointer<vtkRenderWindow> m_glrenWinExport;
|
|
||||||
vtkSmartPointer<DICOMImageViewer> m_imageViewerExport;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DICOMEXPORTER_H
|
#endif // DICOMEXPORTER_H
|
||||||
@@ -6,14 +6,16 @@
|
|||||||
#include <qlist.h>
|
#include <qlist.h>
|
||||||
|
|
||||||
class SeriesImageSet;
|
class SeriesImageSet;
|
||||||
|
class ExtendMedicalImageProperties;
|
||||||
class ExportOptions
|
class ExportOptions
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ExportOptions();
|
explicit ExportOptions();
|
||||||
|
|
||||||
QList<QString> inputData;//the fileName or directory list to export
|
QList<ExtendMedicalImageProperties*> inputData;
|
||||||
|
|
||||||
|
int slice = -1l;
|
||||||
|
|
||||||
int windowWidth;//exported window width
|
int windowWidth;//exported window width
|
||||||
int windowLevel;//exported window level
|
int windowLevel;//exported window level
|
||||||
@@ -41,7 +43,6 @@ public:
|
|||||||
|
|
||||||
QSize customPictureSize;//apply when user choose customsize
|
QSize customPictureSize;//apply when user choose customsize
|
||||||
|
|
||||||
SeriesImageSet *serie;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EXPORTOPTIONS_H
|
#endif // EXPORTOPTIONS_H
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <vtkImageData.h>
|
#include <vtkImageData.h>
|
||||||
#include <vtkImageResize.h>
|
#include <vtkImageResize.h>
|
||||||
#include <vtkBMPWriter.h>
|
|
||||||
#include <vtkNew.h>
|
#include <vtkNew.h>
|
||||||
|
|
||||||
#include "IO/DICOM/DICOMPixelDataHelper.h"
|
#include "IO/DICOM/DICOMPixelDataHelper.h"
|
||||||
|
|||||||
39
src/src/IO/Convert/DICOMToQImageConverter.cpp
Normal file
39
src/src/IO/Convert/DICOMToQImageConverter.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// Created by Krad on 2022/9/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DICOMToQImageConverter.h"
|
||||||
|
|
||||||
|
#include <vtkImageData.h>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
#include "IO/DICOM/DICOMPixelDataHelper.h"
|
||||||
|
|
||||||
|
void DICOMToQImageConverter::save(const char *filename) {
|
||||||
|
if (! m_DICOMFileName.empty()) {
|
||||||
|
void* data = nullptr;
|
||||||
|
int size[2] = {0, 0};
|
||||||
|
if (m_Frame < 0) {
|
||||||
|
DICOMPixelDataHelper::GetRenderedBuffer(m_DICOMFileName.c_str(),
|
||||||
|
data,size, m_Sample, m_Window[0], m_Window[1]);
|
||||||
|
} else {
|
||||||
|
DICOMPixelDataHelper::GetMultiFrameRenderedBuffer(m_DICOMFileName.c_str(),
|
||||||
|
data,size, m_Sample,m_Frame, m_Window[0], m_Window[1]);
|
||||||
|
}
|
||||||
|
if(data){
|
||||||
|
m_Image = new QImage((uchar*)data,size[0],size[1],QImage::Format_RGB888);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage *DICOMToQImageConverter::getQImage() {
|
||||||
|
return m_Image;
|
||||||
|
}
|
||||||
|
|
||||||
|
DICOMToQImageConverter::DICOMToQImageConverter():ConverterBase() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DICOMToQImageConverter::~DICOMToQImageConverter() {
|
||||||
|
|
||||||
|
}
|
||||||
27
src/src/IO/Convert/DICOMToQImageConverter.h
Normal file
27
src/src/IO/Convert/DICOMToQImageConverter.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// Created by Krad on 2022/9/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef OMEGAV_DICOMTOQIMAGECONVERTER_H
|
||||||
|
#define OMEGAV_DICOMTOQIMAGECONVERTER_H
|
||||||
|
#include "ConverterBase.h"
|
||||||
|
class QImage;
|
||||||
|
class DICOMToQImageConverter:public ConverterBase {
|
||||||
|
public:
|
||||||
|
DICOMToQImageConverter();
|
||||||
|
|
||||||
|
~DICOMToQImageConverter() override ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存函数
|
||||||
|
* @param filename 输出的绝对路径
|
||||||
|
*/
|
||||||
|
void save(const char *filename = nullptr) override;
|
||||||
|
QImage* getQImage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage* m_Image = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //OMEGAV_DICOMTOQIMAGECONVERTER_H
|
||||||
@@ -263,6 +263,67 @@ bool DICOMPixelDataHelper::GetRenderedData(const char *path, vtkImageData *data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DICOMPixelDataHelper::GetMultiFrameRenderedData(const char *path, vtkImageData *data, int sample, int frame,
|
||||||
|
double windowLevel, double windowWidth) {
|
||||||
|
auto fileFormat = DICOMFileObjectCache::getInstance()->GetFileObject(path);
|
||||||
|
if (!fileFormat){
|
||||||
|
fileFormat = new DcmFileFormat;
|
||||||
|
if (fileFormat->loadFile(path).good() && fileFormat->loadAllDataIntoMemory().good()) {
|
||||||
|
DICOMFileObjectCache::getInstance()->store(path,fileFormat);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DicomImage dcmImage(fileFormat, fileFormat->getDataset()->getOriginalXfer(), CIF_UsePartialAccessToPixelData,
|
||||||
|
frame, 1);
|
||||||
|
if (dcmImage.getStatus() == EIS_Normal) {
|
||||||
|
RenderToImageData(data, sample, windowLevel, windowWidth, dcmImage);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DICOMPixelDataHelper::GetRenderedBuffer(const char *path, void *&buffer, int*size, int sample, double windowLevel,
|
||||||
|
double windowWidth) {
|
||||||
|
DcmFileFormat fileFormat;
|
||||||
|
if (fileFormat.loadFile(path).good()) {
|
||||||
|
DcmDataset *dset = fileFormat.getDataset();
|
||||||
|
DicomImage dcmImage(&fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
|
||||||
|
size[0] =dcmImage.getWidth();
|
||||||
|
size[1] =dcmImage.getHeight();
|
||||||
|
RenderToBuffer(buffer, sample, windowLevel, windowWidth, dcmImage);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DICOMPixelDataHelper::GetMultiFrameRenderedBuffer(const char *path, void *&buffer,int*size, int sample, int frame,
|
||||||
|
double windowLevel, double windowWidth) {
|
||||||
|
auto fileFormat = DICOMFileObjectCache::getInstance()->GetFileObject(path);
|
||||||
|
if (!fileFormat){
|
||||||
|
fileFormat = new DcmFileFormat;
|
||||||
|
if (fileFormat->loadFile(path).good() && fileFormat->loadAllDataIntoMemory().good()) {
|
||||||
|
DICOMFileObjectCache::getInstance()->store(path,fileFormat);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto dataset = fileFormat->getDataset();
|
||||||
|
DicomImage dcmImage(dataset, dataset->getOriginalXfer(), CIF_UsePartialAccessToPixelData,
|
||||||
|
frame, 1);
|
||||||
|
if (dcmImage.getStatus() == EIS_Normal) {
|
||||||
|
size[0] =dcmImage.getWidth();
|
||||||
|
size[1] =dcmImage.getHeight();
|
||||||
|
RenderToBuffer(buffer, sample, windowLevel, windowWidth, dcmImage);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void DICOMPixelDataHelper::RenderToImageData(vtkImageData *data, int sample, double windowLevel, double windowWidth,
|
void DICOMPixelDataHelper::RenderToImageData(vtkImageData *data, int sample, double windowLevel, double windowWidth,
|
||||||
DicomImage &dcmImage) {//flip for vtk writer
|
DicomImage &dcmImage) {//flip for vtk writer
|
||||||
dcmImage.flipImage(0,1);
|
dcmImage.flipImage(0,1);
|
||||||
@@ -275,23 +336,12 @@ void DICOMPixelDataHelper::RenderToImageData(vtkImageData *data, int sample, dou
|
|||||||
dcmImage.createWindowsDIB(d,dcmImage.getWidth()*dcmImage.getHeight()*3 );
|
dcmImage.createWindowsDIB(d,dcmImage.getWidth()*dcmImage.getHeight()*3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DICOMPixelDataHelper::GetMultiFrameRenderedData(const char *path, vtkImageData *data, int sample, int frame,
|
void DICOMPixelDataHelper::RenderToBuffer(void *&data, int sample, double windowLevel, double windowWidth,
|
||||||
double windowLevel, double windowWidth) {
|
DicomImage &dcmImage) {
|
||||||
auto fileFormat = DICOMFileObjectCache::getInstance()->GetFileObject(path);
|
if (sample == 1){
|
||||||
if (!fileFormat){
|
dcmImage.setWindow(windowLevel, windowWidth);
|
||||||
fileFormat = new DcmFileFormat;
|
|
||||||
if (fileFormat->loadFile(path).good() && fileFormat->loadAllDataIntoMemory().good()) {
|
|
||||||
DICOMFileObjectCache::getInstance()->store(path,fileFormat);
|
|
||||||
DicomImage dcmImage(fileFormat, fileFormat->getDataset()->getOriginalXfer(), CIF_UsePartialAccessToPixelData,
|
|
||||||
frame, 1);
|
|
||||||
if (dcmImage.getStatus() == EIS_Normal) {
|
|
||||||
RenderToImageData(data, sample, windowLevel, windowWidth, dcmImage);
|
|
||||||
delete fileFormat;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete fileFormat;
|
long length = dcmImage.getWidth()*dcmImage.getHeight()*3;
|
||||||
return false;
|
data = new uchar[length];
|
||||||
|
dcmImage.createWindowsDIB(data,length);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool GetRenderedData(const char * path, vtkImageData* data, int sample, double windowLevel, double windowWidth);
|
static bool GetRenderedData(const char * path, vtkImageData* data, int sample, double windowLevel, double windowWidth);
|
||||||
|
|
||||||
|
static bool GetRenderedBuffer(const char * path, void*& buffer,int* size, int sample, double windowLevel, double windowWidth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从Multi-frame类型的DICOM文件中,获取已渲染图像
|
* 从Multi-frame类型的DICOM文件中,获取已渲染图像
|
||||||
* 至vtkImageData中,主要用于DICOM数据的导出,
|
* 至vtkImageData中,主要用于DICOM数据的导出,
|
||||||
@@ -58,6 +60,8 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static bool GetMultiFrameRenderedData(const char * path, vtkImageData* data, int sample,int frame, double windowLevel, double windowWidth);
|
static bool GetMultiFrameRenderedData(const char * path, vtkImageData* data, int sample,int frame, double windowLevel, double windowWidth);
|
||||||
|
|
||||||
|
static bool GetMultiFrameRenderedBuffer(const char * path, void*& data,int* size, int sample,int frame, double windowLevel, double windowWidth);
|
||||||
/**
|
/**
|
||||||
* Get Pixel Data with Rescaled, result is calculate as integer, and arrange as integer.
|
* Get Pixel Data with Rescaled, result is calculate as integer, and arrange as integer.
|
||||||
*
|
*
|
||||||
@@ -172,6 +176,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RenderToImageData(vtkImageData *data, int sample, double windowLevel, double windowWidth, DicomImage &dcmImage);
|
RenderToImageData(vtkImageData *data, int sample, double windowLevel, double windowWidth, DicomImage &dcmImage);
|
||||||
|
|
||||||
|
static void
|
||||||
|
RenderToBuffer(void *&data, int sample, double windowLevel, double windowWidth, DicomImage &dcmImage);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
#include "exportdialog.h"
|
#include "exportdialog.h"
|
||||||
#include "ui_exportdialog.h"
|
#include "ui_exportdialog.h"
|
||||||
|
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
|
#include "UI/Manager/ImageViewManager.h"
|
||||||
|
#include "Deprecated/Export/dicomexporterthread.h"
|
||||||
|
|
||||||
ExportDialog::ExportDialog(QWidget *parent) :
|
ExportDialog::ExportDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::ExportDialog)
|
ui(new Ui::ExportDialog),
|
||||||
|
worker(nullptr)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->progressBar->setVisible(false);
|
ui->progressBar->setVisible(false);
|
||||||
|
ui->rbDICOM->setVisible(false);
|
||||||
|
ui->rbTIFF->setVisible(false);
|
||||||
init();
|
init();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -63,33 +71,28 @@ void ExportDialog::onBtnExportClicked()
|
|||||||
//export files
|
//export files
|
||||||
if (ui->rbCurrentImage->isChecked())//current image
|
if (ui->rbCurrentImage->isChecked())//current image
|
||||||
{
|
{
|
||||||
if (cur_view->hasSeries())
|
if (m_Manager->getCurrentView()->hasSeries())
|
||||||
{
|
{
|
||||||
QString imageName(cur_view->getSeriesInstance()->getCurImageName());
|
auto property = m_Manager->getCurrentView()->getSeriesInstance()->GetProperty();
|
||||||
options.inputData.push_back(imageName);
|
options.inputData.push_back(property);
|
||||||
|
options.slice = m_Manager->getCurrentView()->getSlice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ui->rbCurrentSeries->isChecked())//current series
|
else if (ui->rbCurrentSeries->isChecked())//current series
|
||||||
{
|
{
|
||||||
if (cur_view->hasSeries())
|
if (m_Manager->getCurrentView()->hasSeries())
|
||||||
{
|
{
|
||||||
QString serieName(cur_view->getSeriesInstance()->getSeriesName());
|
auto property = m_Manager->getCurrentView()->getSeriesInstance()->GetProperty();
|
||||||
options.inputData.push_back(serieName);
|
options.inputData.push_back(property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ui->rbAllOpendSeries->isChecked())// all opened series
|
else if (ui->rbAllOpendSeries->isChecked())// all opened series
|
||||||
{
|
{
|
||||||
//disable this function
|
for(auto view:m_Manager->getViewList()){
|
||||||
// InstancesVecType instanceVec;
|
if (view->hasSeries()){
|
||||||
// DicomLoader::GetInstance()->getOpenedInstancesVec(instanceVec);
|
options.inputData.push_back(view->getSeriesInstance()->GetProperty());
|
||||||
// for (int i = 0; i < instanceVec.size(); i++)
|
}
|
||||||
// {
|
}
|
||||||
// SeriesImageSet *instance = instanceVec.at(i);
|
|
||||||
// if (instance != nullptr)
|
|
||||||
// {
|
|
||||||
// options.inputData.push_back(instance->getSeriesName());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui->rbJPEG->isChecked())
|
if (ui->rbJPEG->isChecked())
|
||||||
@@ -139,10 +142,10 @@ void ExportDialog::onBtnExportClicked()
|
|||||||
options.isAnonymization = false;
|
options.isAnonymization = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.windowLevel = cur_view->getImageViewer()->GetColorLevel();
|
options.windowLevel = m_Manager->getCurrentView()->getImageViewer()->GetColorLevel();
|
||||||
options.windowWidth = cur_view->getImageViewer()->GetColorWindow();
|
options.windowWidth = m_Manager->getCurrentView()->getImageViewer()->GetColorWindow();
|
||||||
options.serie = cur_view->getSeriesInstance();
|
|
||||||
DicomExporterThread *worker = new DicomExporterThread(options);
|
worker = new DicomExporterThread(options);
|
||||||
//disconnect(worker, SIGNAL(exportProgress(int, int)), this, SLOT(onExportProgress(int, int)));
|
//disconnect(worker, SIGNAL(exportProgress(int, int)), this, SLOT(onExportProgress(int, int)));
|
||||||
connect(worker, SIGNAL(exportProgress(int, int)), this, SLOT(onExportProgress(int, int)));
|
connect(worker, SIGNAL(exportProgress(int, int)), this, SLOT(onExportProgress(int, int)));
|
||||||
|
|
||||||
@@ -169,14 +172,13 @@ void ExportDialog::onExportFinished()
|
|||||||
{
|
{
|
||||||
ui->progressBar->setVisible(false);
|
ui->progressBar->setVisible(false);
|
||||||
ui->btnExport->setEnabled(true);
|
ui->btnExport->setEnabled(true);
|
||||||
|
if (ui->cbShowAfterExport->isChecked()){
|
||||||
|
QDesktopServices::openUrl(QUrl(QString("file:///%1").arg(ui->edtExportFolder->text())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportDialog::setCurView(DicomImageView *view)
|
void ExportDialog::setViewManager(ImageViewManager *manager)
|
||||||
{
|
{
|
||||||
cur_view = view;
|
m_Manager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void ExportDialog::setViewContainer(ViewContainerWidget *widget)
|
|
||||||
//{
|
|
||||||
// viewContainerWidget = widget;
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -4,13 +4,12 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "Deprecated/Export/exportoptions.h"
|
#include "Deprecated/Export/exportoptions.h"
|
||||||
#include "qdir.h"
|
#include "qdir.h"
|
||||||
#include "Deprecated/Export/dicomexporterthread.h"
|
|
||||||
#include "QFileDialog"
|
#include "QFileDialog"
|
||||||
#include "IO/DICOM/DicomLoader.h"
|
#include "IO/DICOM/DicomLoader.h"
|
||||||
#include "UI/Widget/ImageView/dicomimageview.h"
|
#include "UI/Widget/ImageView/dicomimageview.h"
|
||||||
|
|
||||||
|
class DicomExporterThread;
|
||||||
|
class ImageViewManager;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ExportDialog;
|
class ExportDialog;
|
||||||
@@ -24,7 +23,7 @@ public:
|
|||||||
explicit ExportDialog(QWidget *parent = nullptr);
|
explicit ExportDialog(QWidget *parent = nullptr);
|
||||||
~ExportDialog();
|
~ExportDialog();
|
||||||
//void setViewContainer(ViewContainerWidget *widget)
|
//void setViewContainer(ViewContainerWidget *widget)
|
||||||
void setCurView(DicomImageView *view);
|
void setViewManager(ImageViewManager *manager);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onBtnExportClicked();
|
void onBtnExportClicked();
|
||||||
@@ -40,7 +39,8 @@ private:
|
|||||||
private:
|
private:
|
||||||
Ui::ExportDialog *ui;
|
Ui::ExportDialog *ui;
|
||||||
//ViewContainerWidget *viewContainerWidget;
|
//ViewContainerWidget *viewContainerWidget;
|
||||||
DicomImageView *cur_view;
|
ImageViewManager *m_Manager;
|
||||||
|
DicomExporterThread *worker;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EXPORTDIALOG_H
|
#endif // EXPORTDIALOG_H
|
||||||
|
|||||||
@@ -135,36 +135,9 @@
|
|||||||
<string>Export Location</string>
|
<string>Export Location</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Export Folder</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="edtExportFolder"/>
|
<widget class="QLineEdit" name="edtExportFolder"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QPushButton" name="btnSelectFolder">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Choose Folder...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>FileName Prefix</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="edtFileNamePrefix"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -178,6 +151,40 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export Folder</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>FileName Prefix</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="edtFileNamePrefix"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QPushButton" name="btnSelectFolder">
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::NoFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Choose Folder...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="cbShowAfterExport">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show in Explorer after exported</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -287,8 +294,8 @@
|
|||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="buttonGroup_2"/>
|
|
||||||
<buttongroup name="buttonGroup_3"/>
|
<buttongroup name="buttonGroup_3"/>
|
||||||
|
<buttongroup name="buttonGroup_2"/>
|
||||||
<buttongroup name="buttonGroup"/>
|
<buttongroup name="buttonGroup"/>
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
@@ -495,6 +495,9 @@ void DicomImageView::setSlice(int slice) {
|
|||||||
mImageViewer->SetSlice(slice);
|
mImageViewer->SetSlice(slice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int DicomImageView::getSlice(){
|
||||||
|
return mImageViewer->GetSlice();
|
||||||
|
}
|
||||||
|
|
||||||
void DicomImageView::addSlice(int step) {
|
void DicomImageView::addSlice(int step) {
|
||||||
if (mImageViewer == nullptr) {
|
if (mImageViewer == nullptr) {
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ public:
|
|||||||
|
|
||||||
void setSlice(int slice);
|
void setSlice(int slice);
|
||||||
|
|
||||||
|
int getSlice();
|
||||||
|
|
||||||
|
|
||||||
//Sync zoom
|
//Sync zoom
|
||||||
void setZoomScale(double scale);
|
void setZoomScale(double scale);
|
||||||
|
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ void QDicomViewer::initGeneralTool() {
|
|||||||
connect(ui->toolBar, &DefaultToolBar::save, this, [=] {
|
connect(ui->toolBar, &DefaultToolBar::save, this, [=] {
|
||||||
if (nullptr == exportDialog) {
|
if (nullptr == exportDialog) {
|
||||||
exportDialog = new ExportDialog(this);
|
exportDialog = new ExportDialog(this);
|
||||||
exportDialog->setCurView(ui->viewContainer->getCurrentView());
|
exportDialog->setViewManager(ui->viewContainer->getViewManager());
|
||||||
exportDialog->setModal(false);
|
exportDialog->setModal(false);
|
||||||
}
|
}
|
||||||
exportDialog->show();
|
exportDialog->show();
|
||||||
|
|||||||
Reference in New Issue
Block a user