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