diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index 7a2371bb3..80936e932 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -1,4 +1,5 @@ using AutoMapper; +using DocumentFormat.OpenXml.Bibliography; using DocumentFormat.OpenXml.ExtendedProperties; using ExcelDataReader; using FellowOakDicom; @@ -50,6 +51,7 @@ using System.IO; using System.IO.Compression; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Path = System.IO.Path; @@ -941,9 +943,9 @@ namespace IRaCIS.Core.API.Controllers [HttpGet("download/GetPatientStudyBatchDownload")] - public async Task GetDownloadPatientStudyBatch( [FromServices] IOSSService _oSSService, + public async Task GetDownloadPatientStudyBatch([FromServices] IOSSService _oSSService, [FromServices] IHubContext _downLoadHub, - //[FromServices] IPatientService _patientService, + //[FromServices] IPatientService _patientService, [FromServices] IServiceScopeFactory _serviceScopeFactory, [FromQuery] PatientImageDownloadCommand inCommand) { @@ -958,7 +960,7 @@ namespace IRaCIS.Core.API.Controllers return (result.Data, (SubejctVisitDownload)result.OtherData); } }); - + long receivedSize = 0; long receivedCount = 0; long totalSize = downloadInfo.ImageSize; @@ -1091,67 +1093,79 @@ namespace IRaCIS.Core.API.Controllers if (instance.IsEncapsulated) { - #region 将多帧合并为一帧 + #region 将多帧合并为一帧-在方法里,占用内存,拆成单独方法,不占用内存 - try - { - // 如果你是从 stream 打开 - var dicomFile = await DicomFile.OpenAsync(source); + //try + //{ + // // 如果你是从 stream 打开 + // var dicomFile = await DicomFile.OpenAsync(source); - //获取像素是否为封装形式 - var syntax = dicomFile.Dataset.InternalTransferSyntax; + // //获取像素是否为封装形式 + // var syntax = dicomFile.Dataset.InternalTransferSyntax; - //对于封装像素的文件做转换 - if (syntax.IsEncapsulated) - { - // 获取 Pixel Data 标签 - var pixelData = DicomPixelData.Create(dicomFile.Dataset); + // //对于封装像素的文件做转换 + // if (syntax.IsEncapsulated) + // { + // // 获取 Pixel Data 标签 + // var pixelData = DicomPixelData.Create(dicomFile.Dataset); - // 创建一个新的片段序列 - var newFragments = new DicomOtherByteFragment(DicomTag.PixelData); - // 获取每帧数据并封装为单独的片段 - for (int n = 0; n < pixelData.NumberOfFrames; n++) - { - var frameData = pixelData.GetFrame(n); - newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data)); - } + // // 创建一个新的片段序列 + // var newFragments = new DicomOtherByteFragment(DicomTag.PixelData); + // // 获取每帧数据并封装为单独的片段 + // for (int n = 0; n < pixelData.NumberOfFrames; n++) + // { + // var frameData = pixelData.GetFrame(n); + // newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data)); + // } - var frag = dicomFile.Dataset.GetDicomItem(DicomTag.PixelData); + // var frag = dicomFile.Dataset.GetDicomItem(DicomTag.PixelData); - var originOffsetTable = frag?.OffsetTable; + // var originOffsetTable = frag?.OffsetTable; - newFragments.OffsetTable.AddRange(originOffsetTable?.ToArray()); - // 替换原有的片段序列 - dicomFile.Dataset.AddOrUpdate(newFragments); - } + // newFragments.OffsetTable.AddRange(originOffsetTable?.ToArray()); + // // 替换原有的片段序列 + // dicomFile.Dataset.AddOrUpdate(newFragments); + // } - await dicomFile.SaveAsync(entryStream); + // await dicomFile.SaveAsync(entryStream); - } - catch (Exception ex) - { + //} + //catch (Exception ex) + //{ - Log.Logger.Warning($"处理多帧合并{instance.Path}失败,以原始文件下载: {ex.Message}"); + // Log.Logger.Warning($"处理多帧合并{instance.Path}失败,以原始文件下载: {ex.Message}"); - try - { - await using var source2 = await _oSSService.GetStreamFromOSSAsync(instance.Path); + // try + // { + // await using var source2 = await _oSSService.GetStreamFromOSSAsync(instance.Path); - await source2.CopyToAsync(entryStream, 32 * 1024, abortToken); - } - catch (Exception ex2) - { + // await source2.CopyToAsync(entryStream, 32 * 1024, abortToken); + // } + // catch (Exception ex2) + // { - Log.Logger.Warning($"原始文件下载{instance.Path}失败: {ex2.Message}"); - } - - } + // Log.Logger.Warning($"原始文件下载{instance.Path}失败: {ex2.Message}"); + // } + + //} #endregion + var ok = await TryWriteMergedDicomAsync( + () => _oSSService.GetStreamFromOSSAsync(instance.Path), + entryStream + ); + + if (!ok) + { + await using var source2 = await _oSSService.GetStreamFromOSSAsync(instance.Path); + await source2.CopyToAsync(entryStream, 32 * 1024, abortToken); + } + + } else { @@ -1216,6 +1230,55 @@ namespace IRaCIS.Core.API.Controllers } + private static async Task TryWriteMergedDicomAsync( + Func> sourceFactory, + Stream output) + { + try + { + await using var source = await sourceFactory(); + // 如果你是从 stream 打开 + var dicomFile = await DicomFile.OpenAsync(source); + + //获取像素是否为封装形式 + var syntax = dicomFile.Dataset.InternalTransferSyntax; + + //对于封装像素的文件做转换 + if (syntax.IsEncapsulated) + { + // 获取 Pixel Data 标签 + var pixelData = DicomPixelData.Create(dicomFile.Dataset); + + // 创建一个新的片段序列 + var newFragments = new DicomOtherByteFragment(DicomTag.PixelData); + // 获取每帧数据并封装为单独的片段 + for (int n = 0; n < pixelData.NumberOfFrames; n++) + { + var frameData = pixelData.GetFrame(n); + newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data)); + } + + var frag = dicomFile.Dataset.GetDicomItem(DicomTag.PixelData); + + var originOffsetTable = frag?.OffsetTable; + + newFragments.OffsetTable.AddRange(originOffsetTable?.ToArray()); + // 替换原有的片段序列 + dicomFile.Dataset.AddOrUpdate(newFragments); + } + + await dicomFile.SaveAsync(output); + return true; + } + catch (Exception ex) + { + // 只记录,不传播 + Log.Logger.Warning($"TryWriteMergedDicomAsync failed: {ex.Message}"); + return false; + } + } + + [HttpPost("download/PatientStudyBatchDownloadForm")] public async Task DownloadPatientStudyBatchForm([FromServices] IPatientService _patientService, [FromServices] IOSSService _oSSService, @@ -1883,10 +1946,10 @@ namespace IRaCIS.Core.API.Controllers [HttpGet("download/VisitImageDownload")] - public async Task VisitImageDownload( [FromServices] IOSSService _oSSService, + public async Task VisitImageDownload([FromServices] IOSSService _oSSService, [FromServices] IHubContext _downLoadHub, - //[FromServices] IRepository _trialRepository, - //[FromServices] IPatientService _patientService, + //[FromServices] IRepository _trialRepository, + //[FromServices] IPatientService _patientService, [FromServices] IServiceScopeFactory _serviceScopeFactory, // 注入ServiceScopeFactory [FromQuery] VisitImageDownloadCommand inCommand) { @@ -2044,61 +2107,77 @@ namespace IRaCIS.Core.API.Controllers if (instance.IsEncapsulated) { - #region 将多帧合并为一帧 - try - { - // 如果你是从 stream 打开 - var dicomFile = await DicomFile.OpenAsync(source); + #region 将多帧合并为一帧-在方法里,占用内存,拆成单独方法,不占用内存 - //获取像素是否为封装形式 - var syntax = dicomFile.Dataset.InternalTransferSyntax; - //对于封装像素的文件做转换 - if (syntax.IsEncapsulated) - { - // 获取 Pixel Data 标签 - var pixelData = DicomPixelData.Create(dicomFile.Dataset); - // 创建一个新的片段序列 - var newFragments = new DicomOtherByteFragment(DicomTag.PixelData); - // 获取每帧数据并封装为单独的片段 - for (int n = 0; n < pixelData.NumberOfFrames; n++) - { - var frameData = pixelData.GetFrame(n); - newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data)); - } + //try + //{ + // // 如果你是从 stream 打开 + // var dicomFile = await DicomFile.OpenAsync(source); - var frag = dicomFile.Dataset.GetDicomItem(DicomTag.PixelData); + // //获取像素是否为封装形式 + // var syntax = dicomFile.Dataset.InternalTransferSyntax; - var originOffsetTable = frag?.OffsetTable; + // //对于封装像素的文件做转换 + // if (syntax.IsEncapsulated) + // { + // // 获取 Pixel Data 标签 + // var pixelData = DicomPixelData.Create(dicomFile.Dataset); - newFragments.OffsetTable.AddRange(originOffsetTable?.ToArray()); - // 替换原有的片段序列 - dicomFile.Dataset.AddOrUpdate(newFragments); - } + // // 创建一个新的片段序列 + // var newFragments = new DicomOtherByteFragment(DicomTag.PixelData); + // // 获取每帧数据并封装为单独的片段 + // for (int n = 0; n < pixelData.NumberOfFrames; n++) + // { + // var frameData = pixelData.GetFrame(n); + // newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data)); + // } - await dicomFile.SaveAsync(entryStream); + // var frag = dicomFile.Dataset.GetDicomItem(DicomTag.PixelData); - } - catch (Exception ex) - { + // var originOffsetTable = frag?.OffsetTable; - Log.Logger.Warning($"处理多帧合并{instance.Path}失败: {ex.Message}"); + // newFragments.OffsetTable.AddRange(originOffsetTable?.ToArray()); + // // 替换原有的片段序列 + // dicomFile.Dataset.AddOrUpdate(newFragments); + // } - try - { - await using var source2 = await _oSSService.GetStreamFromOSSAsync(instance.Path); + // await dicomFile.SaveAsync(entryStream); - await source2.CopyToAsync(entryStream, 32 * 1024, abortToken); - } - catch (Exception ex2) - { + //} + //catch (Exception ex) + //{ - Log.Logger.Warning($"原始文件下载{instance.Path}失败: {ex2.Message}"); - } - } + // Log.Logger.Warning($"处理多帧合并{instance.Path}失败,以原始文件下载: {ex.Message}"); + + // try + // { + // await using var source2 = await _oSSService.GetStreamFromOSSAsync(instance.Path); + + // await source2.CopyToAsync(entryStream, 32 * 1024, abortToken); + // } + // catch (Exception ex2) + // { + + // Log.Logger.Warning($"原始文件下载{instance.Path}失败: {ex2.Message}"); + // } + + //} #endregion + + + var ok = await TryWriteMergedDicomAsync( + () => _oSSService.GetStreamFromOSSAsync(instance.Path), + entryStream + ); + + if (!ok) + { + await using var source2 = await _oSSService.GetStreamFromOSSAsync(instance.Path); + await source2.CopyToAsync(entryStream, 32 * 1024, abortToken); + } } else {