Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
commit
0af8e2f017
|
|
@ -61,6 +61,9 @@ namespace IRaCIS.Core.Application.Service
|
|||
[AllowAnonymous]
|
||||
public async Task<IResponseOutput> DownloadTrialImage(Guid trialId)
|
||||
{
|
||||
//找到项目里面未阅片的影像
|
||||
|
||||
|
||||
//var subjectCodeList = new List<string>() { "05002", "07006", "07026" };
|
||||
var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
|
||||
{
|
||||
|
|
@ -213,7 +216,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"下载失败: {ex.Message}");
|
||||
Log.Logger.Error($"下载失败: {ex.Message}");
|
||||
}
|
||||
|
||||
downloadedCount++;
|
||||
|
|
@ -221,7 +224,9 @@ namespace IRaCIS.Core.Application.Service
|
|||
// 每处理50个,输出一次进度(或最后一个时也输出)
|
||||
if (downloadedCount % 50 == 0 || downloadedCount == totalCount)
|
||||
{
|
||||
Console.WriteLine($"已下载 {downloadedCount} / {totalCount} 个文件,完成 {(downloadedCount * 100.0 / totalCount):F2}%");
|
||||
|
||||
Log.Logger.Error($"已下载 {downloadedCount} / {totalCount} 个文件,完成 {(downloadedCount * 100.0 / totalCount):F2}%");
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -1660,7 +1660,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
#endregion
|
||||
|
||||
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id) && t.CheckState == CheckStateEnum.CVPassed))
|
||||
//一致性分析,导致查询出来两条数据
|
||||
//一致性分析,导致查询出来两条数据
|
||||
join visitTask in _visitTaskRepository.Where(t => taskIdList.Contains(t.Id)) on sv.Id equals visitTask.SourceSubjectVisitId into cc
|
||||
from leftVisitTask in cc.DefaultIfEmpty()
|
||||
select new ImageDownloadDto()
|
||||
|
|
@ -2005,6 +2005,21 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取未阅片完成的访视,方便前端调用下载
|
||||
/// </summary>
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<Guid?>> GetTrialUnreadVisitList(Guid trialId)
|
||||
{
|
||||
|
||||
var subjectVisitList = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.SourceSubjectVisitId!=null).Select(t => t.SourceSubjectVisitId)
|
||||
.Distinct().ToListAsync();
|
||||
|
||||
return subjectVisitList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量勾选访视 进行下载
|
||||
/// </summary>
|
||||
|
|
@ -2585,7 +2600,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 后台任务调用,前端忽略该接口
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ using Microsoft.Extensions.Hosting;
|
|||
using NetTopologySuite.Algorithm;
|
||||
using SharpCompress.Common;
|
||||
using SkiaSharp;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
|
|
@ -77,9 +78,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
}
|
||||
|
||||
|
||||
private static async Task<bool> TryWriteMergedDicomAsync(
|
||||
Func<Task<Stream>> sourceFactory,
|
||||
Stream output)
|
||||
private static async Task<bool> TryWriteMergedDicomAsync(Func<Task<Stream>> sourceFactory, Stream output)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -125,6 +124,166 @@ Stream output)
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task<DicomFile> TryWriteSplitDicomAsync(Stream input)
|
||||
{
|
||||
var dicomFile = await DicomFile.OpenAsync(input);
|
||||
|
||||
var numberOfFrames = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 1);
|
||||
|
||||
//多帧处理逻辑
|
||||
if (numberOfFrames > 1)
|
||||
{
|
||||
//一定要有像素数据才处理
|
||||
var pixelData = DicomPixelData.Create(dicomFile.Dataset);
|
||||
|
||||
if (pixelData != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
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 最终使用
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
dicomFile.Dataset.AddOrUpdate(newFragments);
|
||||
|
||||
|
||||
}
|
||||
//传递过来的就是拆分的,但是是没有偏移表的,我需要自己创建偏移表,不然生成缩略图失败
|
||||
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());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 只记录,不传播
|
||||
Log.Logger.Warning($"拆分 failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return dicomFile;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标注遮盖影像 路径后面加了.MaskImage 就是遮盖的新路径
|
||||
/// </summary>
|
||||
|
|
@ -164,7 +323,7 @@ Stream output)
|
|||
|
||||
await using var inputStream = new MemoryStream();
|
||||
|
||||
if (item.IsEncapsulated /*&& item.NumberOfFrames > 1*/)
|
||||
if (item.IsEncapsulated)
|
||||
{
|
||||
|
||||
var ok = await TryWriteMergedDicomAsync(() => _oSSService.GetStreamFromOSSAsync(path), inputStream);
|
||||
|
|
@ -175,42 +334,10 @@ Stream output)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//await using var ms = new MemoryStream();
|
||||
|
||||
//await inputStream.CopyToAsync(ms);
|
||||
|
||||
//ms.Position = 0;
|
||||
|
||||
|
||||
#region 测试废弃
|
||||
//var localPath = Path.Combine(FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment), Path.GetFileName(path));
|
||||
|
||||
//await _oSSService.DownLoadFromOSSAsync(path, localPath);
|
||||
|
||||
//await using var input = File.OpenRead(localPath);
|
||||
|
||||
//var outputPath = Path.Combine(FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment), "After", Path.GetFileName(path));
|
||||
|
||||
//var outputFolder = Path.GetDirectoryName(outputPath);
|
||||
//if (!string.IsNullOrEmpty(outputFolder))
|
||||
//{
|
||||
// Directory.CreateDirectory(outputFolder);
|
||||
//}
|
||||
|
||||
//await using var output = File.Create(outputPath);
|
||||
|
||||
//await DicomPixelMasker.MaskAsync(inputStream, output,inCommand.MaskRegionList);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
var outPutStream = await DicomPixelMasker.MaskAsync(inputStream, inCommand.MaskRegionList);
|
||||
|
||||
var needUploadDicomFile = await TryWriteSplitDicomAsync(outPutStream);
|
||||
|
||||
var prefix = path.Substring(1, path.LastIndexOf('/') - 1);
|
||||
|
||||
//每次都用一个新的名字
|
||||
|
|
@ -234,7 +361,13 @@ Stream output)
|
|||
maskFileName = $"{Path.GetFileName(path)}.MaskDicom_{batchId}";
|
||||
}
|
||||
|
||||
await _oSSService.UploadToOSSAsync(outPutStream, prefix, maskFileName, false);
|
||||
|
||||
// 直接写入内存
|
||||
await using var uploadStream = new MemoryStream();
|
||||
await needUploadDicomFile.SaveAsync(uploadStream);
|
||||
uploadStream.Position = 0;
|
||||
|
||||
await _oSSService.UploadToOSSAsync(uploadStream, prefix, maskFileName, false);
|
||||
|
||||
var newPath = $"/{prefix}/{maskFileName}";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue