// ShowImageDll.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include #include #include #include #include #include #include #include #include #include #include #include"ShowImageDll.h" #include #include #include #include #include #include "vtkAutoInit.h" VTK_MODULE_INIT(vtkRenderingFreeType) VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); using namespace std; class myViewerCallback : public vtkCommand { public: static myViewerCallback* New() { return new myViewerCallback; } void Execute(vtkObject* caller, unsigned long eventId, void* callData) override { cout << eventId << endl; switch (eventId) { case vtkCommand::UserEvent: { //todo 自动调整窗宽窗位 break; } case vtkCommand::TimerEvent: { try { auto id = std::this_thread::get_id(); std::hash hashFunction; long threadIdAsLong = static_cast(hashFunction(id)); vtkVLog(vtkLogger::VERBOSITY_5, "Show image thread ID:" << threadIdAsLong); if (!ImageDll->SMIDQueue.empty()) { unsigned long long frontElement = ImageDll->SMIDQueue.front(); vtkVLog(vtkLogger::VERBOSITY_5, "pop SMID:" << frontElement); ImageDll->SMIDQueue.pop(); WORD* pRaw = (WORD*)SMGetRaw(frontElement); // 现在你可以使用 pRaw 指针 //vtkVLog(vtkLogger::VERBOSITY_5, "WORD* pRaw:"); if (!pRaw) { vtkVLog(vtkLogger::VERBOSITY_5, "smid对应的图像为空"); break; } SMRAWHEADER* npHeader = SMGetRawHeader(frontElement); if (npHeader) { ImageDll->importer->SetDataScalarTypeToUnsignedShort(); // 设置数据类型为 unsigned short ImageDll->importer->SetNumberOfScalarComponents(1); // 设置标量分量数量为1 ImageDll->importer->SetDataExtent(0, npHeader->Width - 1, 0, npHeader->Height - 1, 0, 0); // 设置数据范围 ImageDll->importer->SetWholeExtent(0, npHeader->Width - 1, 0, npHeader->Height - 1, 0, 0); // 设置整个数据范围 ImageDll->importer->SetDataSpacing(1.0, 1.0, 1.0); // 设置数据间距,这里假设为1.0 ImageDll->importer->SetDataOrigin(0.0, 0.0, 0.0); // 设置数据原点,这里假设为0.0 // 将原始数据复制到 vtkImageImport 对象中 ImageDll->importer->CopyImportVoidPointer(pRaw, npHeader->Width * npHeader->Height * sizeof(unsigned short)); ImageDll->importer->Update(); } ImageDll->Viewer->Render(); } } catch (const std::exception& e) { std::string errorMsg(e.what()); vtkVLog(vtkLogger::VERBOSITY_5, "try err:" << errorMsg); throw e; } break; } case vtkCommand::EndInteractionEvent: break; } } ShowImageDll* ImageDll; }; ShowImageDll::ShowImageDll() { //vtkVLog(vtkLogger::VERBOSITY_5, "ShowImageDll"); //vtkOutputWindow::SetGlobalWarningDisplay(1); ViewerCallback = myViewerCallback::New(); ViewerCallback->ImageDll = this; importer = vtkSmartPointer::New(); //ImageData = vtkImageData::New(); Viewer = vtkSmartPointer::New(); Interactor = vtkSmartPointer::New(); //Viewer->RemoveAllObservers(); Viewer->SetupInteractor(Interactor); Interactor->AddObserver(vtkCommand::TimerEvent, ViewerCallback); Interactor->AddObserver(vtkCommand::UserEvent, ViewerCallback, 1.0); Interactor->AddObserver(vtkCommand::WindowLevelEvent, ViewerCallback, 1.0); } void ShowImageDll::SetLoggerParm(int SlicerMode, int level, const std::string& dir) { vtkLogger::FileMode logmode = vtkLogger::TRUNCATE; vtkLogger::Verbosity loglevel = vtkLogger::VERBOSITY_0; if (SlicerMode == 0) { logmode = vtkLogger::TRUNCATE; } else if (SlicerMode == 1) { logmode = vtkLogger::APPEND; } switch (level) { case 0: loglevel = vtkLogger::VERBOSITY_0; break; case 1: loglevel = vtkLogger::VERBOSITY_1; break; case 2: loglevel = vtkLogger::VERBOSITY_2; break; case 3: loglevel = vtkLogger::VERBOSITY_3; break; case 4: loglevel = vtkLogger::VERBOSITY_4; break; case 5: loglevel = vtkLogger::VERBOSITY_5; break; case 6: loglevel = vtkLogger::VERBOSITY_6; break; case 7: loglevel = vtkLogger::VERBOSITY_7; break; case 8: loglevel = vtkLogger::VERBOSITY_8; break; case 9: loglevel = vtkLogger::VERBOSITY_9; break; default: break; } vtkLogger::LogToFile(dir.c_str(), logmode, loglevel); } ShowImageDll::~ShowImageDll() { //vtkVLog(vtkLogger::VERBOSITY_5, "~ShowImageDll"); delete ViewerCallback; } void ShowImageDll::SetPairentID(void* windowID) { if (windowID) { Viewer->SetParentId(windowID); } else { //vtkVLog(vtkLogger::VERBOSITY_5, "windowID为空指针"); } } void ShowImageDll::SetWindowSize(int w, int h) { Viewer->GetRenderWindow()->SetSize(w, h); } // 定义一个互斥锁 //std::mutex smid_mutex; void ShowImageDll::flash(unsigned long long smid) { vtkVLog(vtkLogger::VERBOSITY_5, "push SMID:" << smid); SMIDQueue.push(smid); } void ShowImageDll::Show(unsigned long long smid) { try { //vtkVLog(vtkLogger::VERBOSITY_5, "Enter to display the image, will not exit, unless the program ends"); // auto id = std::this_thread::get_id(); // std::hash hashFunction; // long threadIdAsLong = static_cast(hashFunction(id)); // vtkVLog(vtkLogger::VERBOSITY_5, "Show image thread ID:" << threadIdAsLong); // vtkVLog(vtkLogger::VERBOSITY_5, "SMId " << smid); WORD* pRaw = (WORD*)SMGetRaw(smid); if (!pRaw) { vtkVLog(vtkLogger::VERBOSITY_5, "smid对应的图像为空" << smid); } SMRAWHEADER* npHeader = SMGetRawHeader(smid); if (npHeader) { importer->SetDataScalarTypeToUnsignedShort(); // 设置数据类型为 unsigned short importer->SetNumberOfScalarComponents(1); // 设置标量分量数量为1 importer->SetDataExtent(0, npHeader->Width - 1, 0, npHeader->Height - 1, 0, 0); // 设置数据范围 importer->SetWholeExtent(0, npHeader->Width - 1, 0, npHeader->Height - 1, 0, 0); // 设置整个数据范围 importer->SetDataSpacing(1.0, 1.0, 1.0); // 设置数据间距,这里假设为1.0 importer->SetDataOrigin(0.0, 0.0, 0.0); // 设置数据原点,这里假设为0.0 // 将原始数据复制到 vtkImageImport 对象中 importer->CopyImportVoidPointer(pRaw, npHeader->Width * npHeader->Height * sizeof(unsigned short)); //todo 自动调整窗宽窗位 importer->Update(); int* dimensions = importer->GetOutput()->GetDimensions(); int xMin = dimensions[0] / 4; int xMax = xMin + dimensions[0] / 2; int yMin = dimensions[1] / 4; int yMax = yMin + dimensions[1] / 2; int zMin = dimensions[2] / 4; int zMax = zMin + dimensions[2] / 2; extractVOI = vtkSmartPointer::New(); extractVOI->SetInputData(importer->GetOutput()); extractVOI->SetVOI(xMin, xMax, yMin, yMax, zMin, zMax); extractVOI->Update(); Viewer->SetColorWindow(extractVOI->GetOutput()->GetScalarRange()[1] - extractVOI->GetOutput()->GetScalarRange()[0]); Viewer->SetColorLevel((extractVOI->GetOutput()->GetScalarRange()[1] + extractVOI->GetOutput()->GetScalarRange()[0]) / 2.0); Viewer->SetInputConnection(importer->GetOutputPort()); Viewer->Render(); Interactor->Initialize(); Interactor->CreateRepeatingTimer(100); Interactor->Start(); // vtkVLog(vtkLogger::VERBOSITY_5, "结束显示图像程序退出了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。"); } } catch (const std::exception& e) { std::string errorMsg(e.what()); vtkVLog(vtkLogger::VERBOSITY_5, "try err:" << errorMsg); throw e; } /*auto image = CreateImagedatas(); ImageData->SetDimensions(512, 512, 1); ImageData->AllocateScalars(VTK_UNSIGNED_SHORT, 1); ImageData->GetPointData()->GetScalars()->SetVoidArray(image, 512 * 512 * 2, 1); ImageData->Modified(); Viewer->SetInputData(ImageData); Viewer->Render(); Interactor->Initialize(); Interactor->CreateRepeatingTimer(100); Interactor->Start();*/ }