Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
commit
3fce7b772e
|
|
@ -334,44 +334,227 @@ namespace IRaCIS.Core.SCP.Service
|
||||||
ms.Position = 0;
|
ms.Position = 0;
|
||||||
var dicomFile = DicomFile.Open(ms);
|
var dicomFile = DicomFile.Open(ms);
|
||||||
|
|
||||||
var pixelData = DicomPixelData.Create(dicomFile.Dataset);
|
var numberOfFrames = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 1);
|
||||||
var syntax = pixelData.Syntax;
|
|
||||||
|
|
||||||
// 每个 fragment 固定大小 (64KB 示例,可以自己调整)
|
//多帧处理逻辑
|
||||||
int fragmentSize = 20 * 1024;
|
if (numberOfFrames > 1)
|
||||||
|
|
||||||
if (syntax.IsEncapsulated)
|
|
||||||
{
|
{
|
||||||
var newFragments = new DicomOtherByteFragment(DicomTag.PixelData);
|
//一定要有像素数据才处理
|
||||||
|
var pixelData = DicomPixelData.Create(dicomFile.Dataset);
|
||||||
|
|
||||||
for (int n = 0; n < pixelData.NumberOfFrames; n++)
|
if (pixelData != null)
|
||||||
{
|
{
|
||||||
var frameData = pixelData.GetFrame(n); // 获取完整一帧
|
try
|
||||||
var data = frameData.Data;
|
|
||||||
int offset = 0;
|
|
||||||
|
|
||||||
while (offset < data.Length)
|
|
||||||
{
|
{
|
||||||
int size = Math.Min(fragmentSize, data.Length - offset);
|
|
||||||
var buffer = new byte[size];
|
|
||||||
Buffer.BlockCopy(data, offset, buffer, 0, size);
|
|
||||||
|
|
||||||
newFragments.Fragments.Add(new MemoryByteBuffer(buffer));
|
Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} 开始处理多帧instanceId:{instanceId}");
|
||||||
offset += size;
|
|
||||||
|
var syntax = pixelData.Syntax;
|
||||||
|
|
||||||
|
// 每个 fragment 固定大小 (64KB 示例,可以自己调整)
|
||||||
|
int fragmentSize = 20 * 1024;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var frag = dicomFile.Dataset.GetDicomItem<DicomOtherByteFragment>(DicomTag.PixelData);
|
||||||
|
|
||||||
|
int fragmentCount = frag?.Fragments?.Count() ?? 0;
|
||||||
|
|
||||||
|
var originOffsetTable = frag?.OffsetTable; //有可能没有表,需要自己重建
|
||||||
|
|
||||||
|
var bot = new List<uint>();
|
||||||
|
|
||||||
|
uint botOffset = 0;
|
||||||
|
|
||||||
|
//需要拆成固定片段的
|
||||||
|
if (syntax.IsEncapsulated && fragmentCount == pixelData.NumberOfFrames && numberOfFrames > 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var newFragments = new DicomOtherByteFragment(DicomTag.PixelData);
|
||||||
|
|
||||||
|
#region test
|
||||||
|
//var newDicomFile = dicomFile.Clone();
|
||||||
|
|
||||||
|
//var newDataset = newDicomFile.Dataset;
|
||||||
|
|
||||||
|
//var dstPd = DicomPixelData.Create(newDataset, true);
|
||||||
|
|
||||||
|
//for (int i = 0; i < pixelData.NumberOfFrames; i++)
|
||||||
|
//{
|
||||||
|
// var frame = pixelData.GetFrame(i);
|
||||||
|
|
||||||
|
// dstPd.AddFrame(frame);
|
||||||
|
|
||||||
|
// var data = frame.Data;
|
||||||
|
// int offset = 0;
|
||||||
|
|
||||||
|
// while (offset < data.Length)
|
||||||
|
// {
|
||||||
|
// int size = Math.Min(fragmentSize, data.Length - offset);
|
||||||
|
// var buffer = new byte[size];
|
||||||
|
// Buffer.BlockCopy(data, offset, buffer, 0, size);
|
||||||
|
|
||||||
|
// newFragments.Fragments.Add(new MemoryByteBuffer(buffer));
|
||||||
|
|
||||||
|
// offset += size;
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
//}
|
||||||
|
//var newOffsetTable = newDataset.GetDicomItem<DicomOtherByteFragment>(DicomTag.PixelData).OffsetTable;
|
||||||
|
|
||||||
|
//newFragments.OffsetTable.AddRange(newOffsetTable.ToArray());
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region test fo-dicom auto bot
|
||||||
|
//var newDicomFile = dicomFile.Clone();
|
||||||
|
|
||||||
|
//var newDataset = newDicomFile.Dataset;
|
||||||
|
|
||||||
|
//var dstPd = DicomPixelData.Create(newDataset, true);
|
||||||
|
|
||||||
|
//for (int i = 0; i < pixelData.NumberOfFrames; i++)
|
||||||
|
//{
|
||||||
|
// var frame = pixelData.GetFrame(i);
|
||||||
|
|
||||||
|
// dstPd.AddFrame(frame);
|
||||||
|
//}
|
||||||
|
//var newOffsetTable = newDataset.GetDicomItem<DicomOtherByteFragment>(DicomTag.PixelData).OffsetTable;
|
||||||
|
|
||||||
|
//Console.WriteLine(newOffsetTable.ToJsonStr());
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 最终使用
|
||||||
|
|
||||||
|
for (int n = 0; n < pixelData.NumberOfFrames; n++)
|
||||||
|
{
|
||||||
|
var frameData = pixelData.GetFrame(n); // 获取完整一帧
|
||||||
|
var data = frameData.Data;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
bot.Add(botOffset);
|
||||||
|
|
||||||
|
botOffset += (uint)data.Length;
|
||||||
|
|
||||||
|
|
||||||
|
while (offset < data.Length)
|
||||||
|
{
|
||||||
|
botOffset += 8;
|
||||||
|
|
||||||
|
|
||||||
|
int size = Math.Min(fragmentSize, data.Length - offset);
|
||||||
|
var buffer = new byte[size];
|
||||||
|
Buffer.BlockCopy(data, offset, buffer, 0, size);
|
||||||
|
|
||||||
|
newFragments.Fragments.Add(new MemoryByteBuffer(buffer));
|
||||||
|
|
||||||
|
offset += size;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//保留原始偏移表
|
||||||
|
|
||||||
|
if (originOffsetTable.Count == pixelData.NumberOfFrames)
|
||||||
|
{
|
||||||
|
newFragments.OffsetTable.AddRange(originOffsetTable.ToArray());
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newFragments.OffsetTable.AddRange(bot.ToArray());
|
||||||
|
|
||||||
|
//Console.WriteLine(bot.ToJsonStr());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
dicomFile.Dataset.AddOrUpdate(newFragments);
|
||||||
|
|
||||||
|
|
||||||
|
// 重新保存 dicom 到流
|
||||||
|
ms.SetLength(0);
|
||||||
|
|
||||||
|
dicomFile.Save(ms);
|
||||||
|
}
|
||||||
|
//传递过来的就是拆分的,但是是没有偏移表的,我需要自己创建偏移表,不然生成缩略图失败
|
||||||
|
else if (syntax.IsEncapsulated && fragmentCount > pixelData.NumberOfFrames && originOffsetTable.Count == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint offset = 0;
|
||||||
|
|
||||||
|
bot.Add(offset);
|
||||||
|
|
||||||
|
var fistSize = frag.Fragments.FirstOrDefault()?.Size ?? 0;
|
||||||
|
|
||||||
|
//和上一个大小不一样
|
||||||
|
var isDiffrentBefore = false;
|
||||||
|
|
||||||
|
uint count = 0;
|
||||||
|
|
||||||
|
// 假设你知道每帧对应的 fragment 数量
|
||||||
|
foreach (var frameFragments in frag.Fragments)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (frameFragments.Size == fistSize)
|
||||||
|
{
|
||||||
|
isDiffrentBefore = false;
|
||||||
|
// 累加这一帧所有 fragment 的大小
|
||||||
|
offset += (uint)frameFragments.Size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset += (uint)frameFragments.Size;
|
||||||
|
isDiffrentBefore = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDiffrentBefore)
|
||||||
|
{
|
||||||
|
//每个Fragment 也占用字节
|
||||||
|
offset += 8 * count;
|
||||||
|
bot.Add(offset);
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.RemoveAt(bot.Count - 1);
|
||||||
|
// 设置到新的 PixelData
|
||||||
|
frag.OffsetTable.AddRange(bot.ToArray());
|
||||||
|
|
||||||
|
|
||||||
|
// 重新保存 DICOM 到流
|
||||||
|
ms.SetLength(0);
|
||||||
|
|
||||||
|
dicomFile.Save(ms);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception mutiEx)
|
||||||
|
{
|
||||||
|
Log.Logger.Warning($"CallingAE:{Association.CallingAE} CalledAE:{Association.CalledAE} 处理多帧失败,上传原始文件:{mutiEx.ToString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 替换原 PixelData
|
|
||||||
dicomFile.Dataset.AddOrUpdate(newFragments);
|
|
||||||
|
|
||||||
|
|
||||||
// 重新保存 dicom 到流
|
|
||||||
ms.SetLength(0);
|
|
||||||
dicomFile.Save(ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ms.Position = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
@ -387,6 +570,7 @@ namespace IRaCIS.Core.SCP.Service
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
ms.Position = 0;
|
||||||
|
|
||||||
//irc 从路径最后一截取Guid
|
//irc 从路径最后一截取Guid
|
||||||
storeRelativePath = await ossService.UploadToOSSAsync(ms, ossFolderPath, instanceId.ToString(), false);
|
storeRelativePath = await ossService.UploadToOSSAsync(ms, ossFolderPath, instanceId.ToString(), false);
|
||||||
|
|
@ -429,9 +613,8 @@ namespace IRaCIS.Core.SCP.Service
|
||||||
|
|
||||||
// 上传缩略图到 OSS
|
// 上传缩略图到 OSS
|
||||||
|
|
||||||
var seriesPath = await ossService.UploadToOSSAsync(memoryStream, ossFolderPath, seriesId.ToString() + ".preview.jpg", false);
|
var seriesPath = await ossService.UploadToOSSAsync(memoryStream, ossFolderPath, $"{seriesId.ToString()}_{instanceId.ToString()}.preview.jpg", false);
|
||||||
|
|
||||||
Console.WriteLine(seriesPath + " Id: " + seriesId);
|
|
||||||
|
|
||||||
series.ImageResizePath = seriesPath;
|
series.ImageResizePath = seriesPath;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -334,7 +334,7 @@ namespace IRaCIS.Core.SCP.Service
|
||||||
SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0),
|
SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0),
|
||||||
|
|
||||||
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
|
SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
|
||||||
NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 0),
|
NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 1),
|
||||||
PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty),
|
PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty),
|
||||||
ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
|
ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
|
||||||
FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty),
|
FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty),
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,6 @@ public class OSSService : IOSSService
|
||||||
new Aliyun.OSS.LifecycleRule.LifeCycleTransition
|
new Aliyun.OSS.LifecycleRule.LifeCycleTransition
|
||||||
{
|
{
|
||||||
|
|
||||||
// 关键设置:Days = 0 表示对最后修改时间≤当前的所有文件生效
|
|
||||||
LifeCycleExpiration =
|
LifeCycleExpiration =
|
||||||
{
|
{
|
||||||
Days = 1
|
Days = 1
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,13 @@ namespace IRaCIS.Core.Application.Service
|
||||||
public static int IntValue = 100;
|
public static int IntValue = 100;
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public async Task<IResponseOutput> TestOSS()
|
public async Task<IResponseOutput> TestOSS(StorageClass storageClass)
|
||||||
{
|
{
|
||||||
_IOSSService.SetImmediateArchiveRule("Test-Archive", StorageClass.Archive);
|
if (storageClass == StorageClass.IA || storageClass == StorageClass.Archive || storageClass == StorageClass.ColdArchive || storageClass == StorageClass.DeepColdArchive)
|
||||||
|
{
|
||||||
|
_IOSSService.SetImmediateArchiveRule($"Test-Archive/Archive{(int)storageClass}", storageClass);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return ResponseOutput.Ok();
|
return ResponseOutput.Ok();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue