using FellowOakDicom; using FellowOakDicom.Media; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IRaCIS.Core.Application.Helper { public class StudyDIRInfo { public Guid SubjectVisitId { get; set; } // Study public Guid DicomStudyId { get; set; } public string PatientId { get; set; } public string PatientName { get; set; } public string PatientBirthDate { get; set; } public string PatientSex { get; set; } public string StudyInstanceUid { get; set; } public string StudyId { get; set; } public string DicomStudyDate { get; set; } public string DicomStudyTime { get; set; } public string AccessionNumber { get; set; } public string StudyDescription { get; set; } // Series public string SeriesInstanceUid { get; set; } public string Modality { get; set; } public string DicomSeriesDate { get; set; } public string DicomSeriesTime { get; set; } public int SeriesNumber { get; set; } public string SeriesDescription { get; set; } // Instance public Guid InstanceId { get; set; } public string SopInstanceUid { get; set; } public string SOPClassUID { get; set; } public int InstanceNumber { get; set; } public string MediaStorageSOPClassUID { get; set; } public string MediaStorageSOPInstanceUID { get; set; } public string TransferSytaxUID { get; set; } } public static class DicomDIRHelper { public static async Task> GenerateStudyDIRAndUploadAsync(List list, string ossFolder, IOSSService _oSSService) { var dic = new Dictionary(); var mappings = new List(); int index = 1; var dicomDir = new DicomDirectory(); foreach (var item in list.OrderBy(t => t.SeriesNumber).ThenBy(t => t.InstanceNumber)) { var dicomUid = DicomUID.Enumerate().FirstOrDefault(uid => uid.UID == item.TransferSytaxUID); if (dicomUid != null) { var ts = DicomTransferSyntax.Query(dicomUid); var dataset = new DicomDataset(ts) { { DicomTag.PatientID, item.PatientId ?? string.Empty }, { DicomTag.PatientName, item.PatientName ?? string.Empty }, { DicomTag.PatientBirthDate, item.PatientBirthDate ?? string.Empty }, { DicomTag.PatientSex, item.PatientSex ?? string.Empty }, { DicomTag.StudyInstanceUID, item.StudyInstanceUid ?? string.Empty }, { DicomTag.StudyID, item.StudyId ?? string.Empty }, { DicomTag.StudyDate, item.DicomStudyDate ?? string.Empty }, { DicomTag.StudyTime, item.DicomStudyTime ?? string.Empty }, { DicomTag.AccessionNumber, item.AccessionNumber ?? string.Empty }, { DicomTag.StudyDescription, item.StudyDescription ?? string.Empty }, { DicomTag.SeriesInstanceUID, item.SeriesInstanceUid ?? string.Empty }, { DicomTag.Modality, item.Modality ?? string.Empty }, { DicomTag.SeriesDate, item.DicomSeriesDate ?? string.Empty }, { DicomTag.SeriesTime, item.DicomSeriesTime ?? string.Empty }, { DicomTag.SeriesNumber, item.SeriesNumber.ToString() ?? string.Empty }, { DicomTag.SeriesDescription, item.SeriesDescription ?? string.Empty }, { DicomTag.SOPInstanceUID, item.SopInstanceUid ?? string.Empty }, { DicomTag.SOPClassUID, item.SOPClassUID ?? string.Empty }, { DicomTag.InstanceNumber, item.InstanceNumber.ToString() ?? string.Empty }, { DicomTag.MediaStorageSOPClassUID, item.MediaStorageSOPClassUID ?? string.Empty }, { DicomTag.MediaStorageSOPInstanceUID, item.MediaStorageSOPInstanceUID ?? string.Empty }, { DicomTag.TransferSyntaxUID, item.TransferSytaxUID ?? string.Empty }, }; var dicomFile = new DicomFile(dataset); // 文件名递增格式:IM_00001, IM_00002, ... string filename = $@"IMAGE/IM_{index:D5}"; // :D5 表示补足5位 mappings.Add($"{filename} => {item.InstanceId}"); dic.Add(item.InstanceId.ToString(), Path.GetFileName(filename)); dicomDir.AddFile(dicomFile, filename); index++; } } //有实际的文件 if (mappings.Count > 0) { #region 写入临时路径 var tempFilePath = Path.GetTempFileName(); // 保存 DICOMDIR 到临时文件 不能直接写入到流种 await dicomDir.SaveAsync(tempFilePath); using (var memoryStream = new MemoryStream(File.ReadAllBytes(tempFilePath))) { // 重置流位置 memoryStream.Position = 0; await _oSSService.UploadToOSSAsync(memoryStream, ossFolder, "DICOMDIR", false); } //清理临时文件 File.Delete(tempFilePath); #endregion #region 映射上传 // 将映射写入内存流 var mappingText = string.Join(Environment.NewLine, mappings); await using var mappingStream = new MemoryStream(Encoding.UTF8.GetBytes(mappingText)); await _oSSService.UploadToOSSAsync(mappingStream, ossFolder, $"Download_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}", false); #endregion } return dic; } public static StudyDIRInfo ReadDicomDIRInfo(DicomFile dicomFile) { var dataset = dicomFile.Dataset; var info = new StudyDIRInfo { PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty), PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty), PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty), PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty), StudyInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty), StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty), DicomStudyDate = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty), DicomStudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty), AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty), StudyDescription = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty), SeriesInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SeriesInstanceUID, string.Empty), Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty), DicomSeriesDate = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty), DicomSeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty), SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1), SeriesDescription = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty), SopInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty), SOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.SOPClassUID, string.Empty), InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1), MediaStorageSOPClassUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty), MediaStorageSOPInstanceUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty), TransferSytaxUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.TransferSyntaxUID, string.Empty) }; return info; } } }