近来在做一个医疗项目,此中设计到医学影像数据Dicom文件的传输,此中的一个功能是必要Dicom文件和PACS系统举行互通,就是能将本地的DICOM文件传输到PACS系统,并且本地系统能查询到PACS系统数据并下载。针对将文件上传到PACS系统。之前我们项目中都是利用的C++来处理的。C#的项目都是通过调用C++封装的接口来实现与PACS的数据传输。我这里做了实现了两种方案,都是纯C#实现,并且都已走通。
方式一:通过C#的开源库fo-dicom来实现的数据传输,直接通过NuGet安装相关的依赖包,好比我这里是NET6,搜索并下载fo-dicom.NetCore,假如是.net framework版本的,应该是搜索fo-dicom安装即可。也可以去github上下载源码笔记编译。这里直接上代码,代码中都有注释。
方式一:基于fo-dicom的开源库来实现- /// <summary>
- /// 发送Dicom数据到PACS系统,C#实现方式
- /// </summary>
- /// <param name="dicomFilePath">Dicom文件路径</param>
- /// <param name="nodeName">Dicom节点名称,我这里是根据节点来找到对应的PACS服务器信息</param>
- /// <returns></returns>
- public async Task SendDicomFileToPacs(string dicomFilePath, string nodeName)
- {
- DICOMConnectParameterWrapper connectPara = new DICOMConnectParameterWrapper();
- DICOMConnectKeyWrapper connectKey = new DICOMConnectKeyWrapper();
- bool isSecure = false;
- if (GetConnectionParameter(nodeName, ref connectPara, ref connectKey, ref isSecure) == false)
- {
- await Task.CompletedTask; //如果找不到配置的PACS服务器信息,直接返回
- }
- //connectPara.ServiceIP=PACS服务器IP,connectPara.ServicePort=PACS服务器端口,connectPara.ClientAETitle=客户端AETITLE,connectPara.ServiceAETitle=PACS服务器AEtitle
- var client = new Dicom.Network.Client.DicomClient(connectPara.ServiceIP, Convert.ToInt32(connectPara.ServicePort), false, connectPara.ClientAETitle, connectPara.ServiceAETitle);
- var file = DicomFile.Open(@dicomFilePath);
- client.AssociationAccepted += (sender, args) =>
- {
- Console.WriteLine("Association accepted");
- };
- client.AssociationRejected += (sender, args) =>
- {
- Console.WriteLine("Association rejected");
- };
- client.RequestTimedOut += (sender, args) =>
- {
- Console.WriteLine("DIMSE timeout");
- };
- client.StateChanged += (sender, args) =>
- {
- Console.WriteLine("DIMSE progress: {0} / {1}", args.NewState.ToString(), args.OldState.ToString());
- };
- await client.AddRequestAsync(new Dicom.Network.DicomCStoreRequest(@dicomFilePath)
- {
- OnResponseReceived = (req, res) =>
- {
- Console.WriteLine($"C-STORE response: {res.Status}");
- }
- });
- try
- {
- await client.SendAsync();
- }
- catch(Exception ex)
- {
- Console.WriteLine("An error occurred while sending the DICOM file: {0}", ex.Message);
- }
-
- }
复制代码 在方式一中,这里封装的是针对简单的传输。是在PACS系统不必要认证等前提下,就是说数据传输不必要加密认证等。 当然,实际利用时,PACS系统有些会有安全和认证机制,我们必要根据实际情况处理。我这里的方法GetConnectionParameter是封装的根据PACS节点名来找到对应的PACS的配置,好比PACS的服务器IP,Port,是否加密,证书,等等。假如有加密或认证什么的,还必要进一步处理,我这里会涉及到多个PACS服务器系统,我是在系统中做了配置,通过nodeName来找到对一个的PACS系统的信息。
GetConnectionParameter获取PACS服务器信息- private bool GetConnectionParameter(string nodeName, ref DICOMConnectParameterWrapper connectPara, ref DICOMConnectKeyWrapper connectKey, ref bool isSecure)
- {
- if (!DicomPeerDictionary.ContainsKey(nodeName))
- {
- return false;
- }
- DicomNodeBase node = DicomPeerDictionary[nodeName];
- connectPara.ClientAETitle = ConfigInfo.DicomNode_ClientAETitle; //客户端AETitle
- connectPara.ClientIP = CommonHelper.GetAddressIP(); //客户端IP地址
- connectPara.ClientPort = ConfigInfo.DicomNode_ClientPort; //客户端端口
- connectPara.ServiceAETitle = node.AETitle; //PACS服务器AETitle
- connectPara.ServiceIP = node.IP; //PACS服务器IP
- connectPara.ServicePort = node.Port; //PACS服务器端口
- connectKey.PrivateKey = node.PrivateKeyPath; //秘钥
- connectKey.CACertificateFile = node.CACertificatePath; //CA证书文件
- connectKey.CertificateFile = node.CertificatePath; //证书
- isSecure = node.IsEncryptionChecked; //是否加密
- return true;
- }
复制代码 利用的时候就简单了,直接调用SendDicomFileToPacs方法,传入Dicom文件的全路径,以及PACS配置的NodeName即可。另外,我这里用的fo-dicom的库是fo-dicom.netcore的4.0.8版本的,每个版本的可能会有些差别。这里还有涉及到从PACS查询数据,下载数据的功能,这个在fo-dicom库中可以利用类Dicom.Network.DicomCFindRequest来举行操纵,此中封装了好几个查询的方法:CreateStudyQuery,CreateSeriesQuery,CreatePatientQuery,CreateImageQuery,CreateWorklistQuery,然后询请求的响应通过类中的OnResponseReceived事件处理,可以获取到查询效果的数据集。我们可以将查询效果的数据集直接转换成一个DICOM文件保存到本地,这样就可以实现下载功能。
方式二:传输数据到PACS的实现方式
这种方式我是针对Orthanc的PACS系统的实现方式,,Orthanc本身有提供API接口,只必要调用其接口实现数据传输即可。利用的时候传入Dicom文件路径和PACS服务器URL即可。这里代码如下。
发送数据到Orthanc的PACS系统- /// <summary>
- /// 发送数据到Orthanc的PACS系统,C#实现方式,直接调用Orthanc的API来实现
- /// </summary>
- /// <param name="dicomFilePath">Dicom文件路径</param>
- /// <param name="orthancUrl">PACS系统的URL,类似 http://localhost:8042</param>
- public void UploadDicomToOrthanc(string dicomFilePath, string orthancUrl)
- {
- using (var client = new HttpClient())
- {
- using (var content = new MultipartFormDataContent())
- {
- // 添加文件内容
- var fileStream = File.OpenRead(dicomFilePath);
- var streamContent = new StreamContent(fileStream);
- content.Add(streamContent, "file", Path.GetFileName(dicomFilePath));
- // 发送POST请求到Orthanc服务器
- var response = client.PostAsync($"{orthancUrl}/instances", content).Result;
- if (response.IsSuccessStatusCode)
- {
- Console.WriteLine("DICOM文件上传成功。");
- }
- else
- {
- Console.WriteLine("上传失败,HTTP状态码:" + response.StatusCode);
- }
- }
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |