void ThumbnailsCommand::Execute() { NotificarProgreso(0.05f,_Std("Creating Thumbnail...")); m_Error = true; GTRACE("Arrancando comando generar thumbnails " << m_pThumbParams->m_ruta) //std::string tarea_Std("Generando thumbnails..."); //pillamos el uid m_pThumbParams->m_fileModel = GNC::GCS::HistoryController::Instance()->GetFileModel(m_pThumbParams->m_file_pk); if(m_pThumbParams->m_fileModel.sopiuid.empty()) { wxBitmap bmp = GinkgoResourcesManager::History::GetIcoUnknownFile(); m_pThumbParams->m_wxImg = new wxImage(); (*m_pThumbParams->m_wxImg) = bmp.ConvertToImage(); GuardarImagen(); m_Error = false; return; } //if is wado linked... if (m_pThumbParams->m_fileModel.location == GNC::GCS::IHistoryController::TL_WadoLinked) { wxBitmap bmp = GinkgoResourcesManager::History::GetIcoWadoLinkedPreview(); m_pThumbParams->m_wxImg = new wxImage(); (*m_pThumbParams->m_wxImg) = bmp.ConvertToImage(); m_Error = false; return; } //comprobar si el thumbnail ya estaba generado m_pThumbParams->m_wxImg = GetImageFromBD(); if(m_pThumbParams->m_wxImg != NULL) { GTRACE("Saliendo generar thumbnails salida2 " << m_pThumbParams->m_ruta); NotificarProgreso(1.0f,_Std("Creating Thumbnail...")); m_Error = false; return; } else { //try to make thumbnail with extensions... ::GNC::ControladorExtensiones::ListaModulos listaModulos = ::GNC::ControladorExtensiones::Instance()->Modulos(); for(GNC::ControladorExtensiones::IteradorListaModulos it=listaModulos.begin(); it!=listaModulos.end(); ++it) { GNC::GCS::IModuleController* modulo = (*it).second; GNC::GCS::Ptr<ImgProxy<UCHAR3> >pImgCapture(new ImgProxy<UCHAR3>()); if (modulo->MakeThumbnail(m_pThumbParams->m_fileModel, *pImgCapture)) { wxImage* pImage = new wxImage(pImgCapture->anchura, pImgCapture->altura, (unsigned char*)pImgCapture->data, true); if (pImage->IsOk()) { double scaleX = ((double) SIZE_THUMBNAILS)/((double) pImgCapture->anchura); double scaleY = ((double) SIZE_THUMBNAILS)/((double) pImgCapture->altura); if (scaleX < 1.0 || scaleY < 1.0) { double scale = wxMin(scaleX, scaleY); int newWidth = (int) (scale * pImgCapture->anchura); int newHeight = (int) (scale * pImgCapture->altura); m_pThumbParams->m_wxImg = new wxImage(pImage->Scale(newWidth, newHeight, wxIMAGE_QUALITY_HIGH)); } else { m_pThumbParams->m_wxImg = new wxImage(*pImage); } delete pImage; GuardarImagen(); m_Error = false; return; } } } if (m_pThumbParams->m_fileModel.tsuid== GKUID_MPEG2MainProfileAtMainLevelTransferSyntax || m_pThumbParams->m_fileModel.tsuid == GKUID_MPEG2MainProfileAtHighLevelTransferSyntax) { wxBitmap bmp = GinkgoResourcesManager::History::GetMoviePreview(); m_pThumbParams->m_wxImg = new wxImage(); (*m_pThumbParams->m_wxImg) = bmp.ConvertToImage(); GuardarImagen(); m_Error = false; return; } if (m_pThumbParams->m_fileModel.sopcuid == GKUID_EncapsulatedPDFStorage) { wxBitmap bmp = GinkgoResourcesManager::History::GetPDFPreview(); m_pThumbParams->m_wxImg = new wxImage(); (*m_pThumbParams->m_wxImg) = bmp.ConvertToImage(); m_Error = false; return; } double size[2] = {0.0, 0.0}; int dimensions[3] = {0, 0, 0}; double spacing[3] = {0.0, 0.0, 0.0}; double origin[3] = {0.0, 0.0, 0.0}; size[0] = SIZE_THUMBNAILS; size[1] = SIZE_THUMBNAILS; { //esto es una nyapa para recuperarnos de errores, antes de leer guardamos en bbdd una imagen negra, si finalmente //el thumbnail se genera bien pues se mete, si no pues se quedara con unknown wxImage img = GinkgoResourcesManager::History::GetIcoUnknownFile().ConvertToImage(); m_pThumbParams->m_wxImg = &img; GuardarImagen(); m_pThumbParams->m_wxImg = NULL; } typedef itk::RGBPixel<unsigned char> PixelType; typedef itk::Image< PixelType, 2 > ImageType; typedef itk::ImageRegionConstIterator< ImageType > ImageIteratorType; typedef itk::VTKImageToImageFilter<ImageType> TipoFiltro; ImageType::SizeType outputSize; ImageType::SpacingType outputSpacing; ImageType::PointType outputOrigin; vtkSmartPointer<vtkImageShiftScale> normalizeFilter = vtkSmartPointer<vtkImageShiftScale>::New(); outputSize[0] = size[0]; outputSize[1] = size[1]; unsigned long imgsize = outputSize[0] * outputSize[1] * sizeof(unsigned char) * 3; unsigned char* data = new unsigned char[imgsize]; try { GNC::StreamingLoader loader; loader.SetInput(m_pThumbParams->m_fileModel.real_path); loader.GetDimensions(dimensions); loader.GetSpacing(spacing); loader.SetOutputOrigin(origin); vtkSmartPointer<vtkImageReslice> pReslice = vtkSmartPointer<vtkImageReslice>::New(); TipoFiltro::Pointer VTK2ITKfiltro = TipoFiltro::New(); vtkSmartPointer<vtkMatrix4x4> resliceAxes = vtkSmartPointer<vtkMatrix4x4>::New(); if ( dimensions[0] == 0 || dimensions[1] == 0 || spacing[0] == 0 || spacing[1] == 0) { if ( !loader.IsSignalFile()) { m_Error = true; delete[] data; data = NULL; LOG_WARN("GenerarThumbnails", "Error: imagen de tamaƱo 0, generaciĆ³n ignorada."); return; } NotificarProgreso(0.8f,_Std("Creating Thumbnail...")); memset(data, 0, imgsize); double x, y; unsigned int ix, iy; const double resx = M_PI * 4.0 / (double) outputSize[0]; const double resy = (double) 0.25 * outputSize[1]; const double sy = (double) 0.5 * outputSize[1]; for (ix = 0; ix < outputSize[0]; ++ix) { x = ((double) ix); y = resy * std::sin(x * resx); y += sy; iy = std::max<int>(0, std::min<int>(outputSize[0] - 1, (int) std::floor(y + 0.5)) ); unsigned char* pixel = data + (3 * (iy * outputSize[0] + ix)); pixel[0] = 0; pixel[1] = 255; pixel[2] = 128; } } else { pReslice->SetInputConnection(loader.GetOutputPort()); pReslice->SetOutputDimensionality(2); pReslice->SetResliceAxesDirectionCosines(1, 0, 0, 0, 1, 0, 0, 0, 1); outputSize[0] = size[0]; outputSize[1] = size[1]; double dInputSize[3]; dInputSize[0] = (double)dimensions[0]; dInputSize[1] = (double)dimensions[1]; dInputSize[2] = 1.0; double dOutputSize[3]; dOutputSize[0] = (double)outputSize[0]; dOutputSize[1] = (double)outputSize[1]; dOutputSize[2] = 1.0; double sX = dOutputSize[0] / dInputSize[0]; double sY = dOutputSize[1] / dInputSize[1]; double s = std::min<double>(sX, sY); double dOutputSpacing[3]; dOutputSpacing[0] = spacing[0] / s; dOutputSpacing[1] = spacing[1] / s; dOutputSpacing[2] = spacing[2]; pReslice->SetOutputExtent(0, dOutputSize[0] - 1, 0, dOutputSize[1] - 1, 0, 1); pReslice->SetOutputSpacing(dOutputSpacing); //moves image vertical or horizontal to center thumbnail. x + => left; - => right. y + => up; - => down //formula is tested with color images and images with spacing and origin origin[0] = (((s - sX) * dInputSize[0] / 2.0f) / s) * spacing[0]; origin[1] = (((s - sY) * dInputSize[1] / 2.0f) / s) * spacing[0]; pReslice->SetOutputOrigin(origin); pReslice->SetInterpolationModeToCubic(); pReslice->Update(); vtkImageData *timg = pReslice->GetOutput(); if(timg->GetNumberOfScalarComponents() > 1) { normalizeFilter->SetInputConnection(pReslice->GetOutputPort()); normalizeFilter->SetOutputScalarTypeToUnsignedChar(); if (timg->GetScalarType() != VTK_UNSIGNED_CHAR) { double range[2]; timg->GetScalarRange(range); double diff = range[1]-range[0]; if (diff > std::numeric_limits<double>::epsilon()) { normalizeFilter->SetShift(-range[0]); normalizeFilter->SetScale(255.0/(range[1]-range[0])); } } normalizeFilter->Update(); VTK2ITKfiltro->SetInput(normalizeFilter->GetOutput()); } else { vtkSmartPointer<vtkImageMapToColors> pImageMap = vtkSmartPointer<vtkImageMapToColors>::New(); pImageMap->SetInputConnection(pReslice->GetOutputPort()); vtkSmartPointer<vtkLookupTable> pLookupTable = vtkLookupTableManager::GetLinearLookupTable(); pImageMap->SetLookupTable(pLookupTable); pImageMap->SetOutputFormatToRGB(); if (timg->GetNumberOfScalarComponents() == 1) { double window, level; if (loader.GetDefaultWindowLevel(window,level) && window != 0.0) { double v_min = (level) - 0.5 * window; double v_max = level + 0.5 * window; pLookupTable->SetRange(v_min, v_max); } else { double range[2]; timg->GetScalarRange(range); double diff = range[1]-range[0]; window = range[1]-range[0]; level = 0.5*(range[1]+range[0]); if (diff > std::numeric_limits<double>::epsilon()) { double v_min = (level) - 0.5 * window; double v_max = level + 0.5 * window; pLookupTable->SetRange(v_min, v_max); } } } pImageMap->SetLookupTable(pLookupTable); pImageMap->Update(); VTK2ITKfiltro->SetInput( pImageMap->GetOutput()); } NotificarProgreso(0.6f,_Std("Creating Thumbnail...")); VTK2ITKfiltro->GetImporter()->UpdateLargestPossibleRegion(); const ImageType* img = VTK2ITKfiltro->GetOutput(); NotificarProgreso(0.8f,_Std("Creating Thumbnail...")); ImageType::RegionType region = img->GetLargestPossibleRegion(); ImageIteratorType it (img, region); std::cout << "imgsize = " << imgsize << std::endl; std::cout << "region = "; region.Print(std::cout); std::cout << std::endl; unsigned long off = 0; for (it.GoToBegin(); !it.IsAtEnd() && off < imgsize; ++it) { const ImageType::PixelType& pixel = it.Value(); data[off++] = pixel.GetRed(); data[off++] = pixel.GetGreen(); data[off++] = pixel.GetBlue(); } } m_pThumbParams->m_wxImg = new wxImage(outputSize[0], outputSize[1], data, false); GuardarImagen(); NotificarProgreso(1.0f,_Std("Generating thumbnail ...")); m_Error = false; } catch (GNC::GCS::ControladorCargaException &ex1) { LOG_ERROR("GenerarThumnails", "Unable to create thumbnail for file [" << m_pThumbParams->m_file_pk << "]: " << ex1.str()); if (data != NULL) { delete[] data; data = NULL; } //si se cancela el comando return; } catch(itk::ExceptionObject& ex2) { LOG_ERROR("GenerarThumnails", "Unable to create thumbnail for file [" << m_pThumbParams->m_file_pk << "]: " << ex2.GetDescription()); //std::string descr = ex2.GetDescription(); if (data != NULL) { delete[] data; data = NULL; } return; } catch(std::exception &ex3) { LOG_ERROR("GenerarThumnails", "Unable to create thumbnail for file [" << m_pThumbParams->m_file_pk << "]: " << ex3.what()); //std::string descr = ex3.what(); //si se cancela el comando if (data != NULL) { delete[] data; data = NULL; } return; } catch(...) { LOG_ERROR("GenerarThumnails", "Unable to create thumbnail for file [" << m_pThumbParams->m_file_pk << "]: Internal error" ); //si se cancela el comando if (data != NULL) { delete[] data; data = NULL; } return; } } }