将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 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<IActionResult> GetDownloadPatientStudyBatch( [FromServices] IOSSService _oSSService,
|
||||
public async Task<IActionResult> GetDownloadPatientStudyBatch([FromServices] IOSSService _oSSService,
|
||||
[FromServices] IHubContext<DownloadHub, IDownloadClient> _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<DicomOtherByteFragment>(DicomTag.PixelData);
|
||||
// var frag = dicomFile.Dataset.GetDicomItem<DicomOtherByteFragment>(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<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")]
|
||||
public async Task<IActionResult> DownloadPatientStudyBatchForm([FromServices] IPatientService _patientService, [FromServices] IOSSService _oSSService,
|
||||
|
|
@ -1883,10 +1946,10 @@ namespace IRaCIS.Core.API.Controllers
|
|||
|
||||
|
||||
[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] IRepository<Trial> _trialRepository,
|
||||
//[FromServices] IPatientService _patientService,
|
||||
//[FromServices] IRepository<Trial> _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<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());
|
||||
// 替换原有的片段序列
|
||||
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<DicomOtherByteFragment>(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
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue