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 running Details

Uat_IRC_Net8
he 2026-05-07 11:27:11 +08:00
commit f6c9490124
6 changed files with 129 additions and 15 deletions

View File

@ -1073,6 +1073,13 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
{
BackBatchGetToken();
// 确保目标目录存在
string directory = Path.GetDirectoryName(localFilePath);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
ossRelativePath = ossRelativePath.TrimStart('/');
try
{

View File

@ -118,9 +118,9 @@ namespace IRaCIS.Core.Application.Service
{
var downloadJobs = new List<Func<Task>>();
var rootFolder = @"E:\DownloadImage";
//var rootFolder = @"E:\DownloadImage";
//var rootFolder = FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment);
var rootFolder = FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment);
// 获取无效字符(系统定义的)
string invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());

View File

@ -741,6 +741,7 @@ namespace IRaCIS.Core.Application.Contracts
public class DownloadDicomInstanceDto
{
public int NumberOfFrames { get; set; }
public bool IsEncapsulated { get; set; }
public Guid InstanceId { get; set; }
public string FileName { get; set; }
@ -1171,4 +1172,6 @@ namespace IRaCIS.Core.Application.Contracts
public string Path { get; set; }
}
}

View File

@ -1,13 +1,21 @@
using IRaCIS.Core.Application.Contracts;
using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.IO.Buffer;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MathNet.Numerics;
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using NetTopologySuite.Algorithm;
using SharpCompress.Common;
using SkiaSharp;
using System.Drawing;
using ZiggyCreatures.Caching.Fusion;
@ -29,7 +37,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
IRepository<SystemAnonymization> _systemAnonymizationRepository,
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
IDistributedLockProvider _distributedLockProvider, IOSSService _oSSService,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IStudyService
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache, IWebHostEnvironment _hostEnvironment) : BaseService, IStudyService
{
@ -69,6 +77,54 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
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;
}
}
/// <summary>
/// 标注遮盖影像 路径后面加了.MaskImage 就是遮盖的新路径
/// </summary>
@ -81,16 +137,16 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
var idPathList = new List<InstanceIdPath>();
var idPathList = new List<DownloadDicomInstanceDto>();
if (inCommand.SeriesId == null && inCommand.InstanceIdList != null)
{
idPathList = await _dicomInstanceRepository.Where(t => inCommand.InstanceIdList.Contains(t.Id)).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
idPathList = await _dicomInstanceRepository.Where(t => inCommand.InstanceIdList.Contains(t.Id)).ProjectTo<DownloadDicomInstanceDto>(_mapper.ConfigurationProvider).ToListAsync();
}
else
{
idPathList = await _dicomInstanceRepository.Where(t => t.SeriesId == inCommand.SeriesId).Select(t => new InstanceIdPath { Id = t.Id, Path = t.Path }).ToListAsync();
idPathList = await _dicomInstanceRepository.Where(t => t.SeriesId == inCommand.SeriesId).ProjectTo<DownloadDicomInstanceDto>(_mapper.ConfigurationProvider).ToListAsync();
}
var errorList = new List<InstanceIdPath>();
@ -105,7 +161,53 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
try
{
var inputStream = await _oSSService.GetStreamFromOSSAsync(path);
await using var inputStream = new MemoryStream();
if (item.IsEncapsulated /*&& item.NumberOfFrames > 1*/)
{
var ok = await TryWriteMergedDicomAsync(() => _oSSService.GetStreamFromOSSAsync(path), inputStream);
}
else
{
await (await _oSSService.GetStreamFromOSSAsync(path)).CopyToAsync(inputStream);
}
//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, outputinCommand.MaskRegionList);
#endregion
var outPutStream = await DicomPixelMasker.MaskAsync(inputStream, inCommand.MaskRegionList);
@ -120,7 +222,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
await _oSSService.DeleteFromPrefix(path, true); //清理缓存的里面的遮盖图,多次遮盖同一张图时,清除缓存很重要
//本身就是遮盖的图那么就要要替换guid
var length = Guid.Empty.ToString().Length + ".MaskDicom_".Length ;
var length = Guid.Empty.ToString().Length + ".MaskDicom_".Length;
var restorePath = item.Path[..^length];
@ -136,14 +238,14 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
var newPath = $"/{prefix}/{maskFileName}";
okList.Add(new InstanceIdPath() { Id = item.Id, Path = newPath });
okList.Add(new InstanceIdPath() { Id = item.InstanceId, Path = newPath });
await _dicomInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new DicomInstance() { Path = newPath, IsMasked = true });
await _dicomInstanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.InstanceId, u => new DicomInstance() { Path = newPath, IsMasked = true });
}
catch (Exception ex)
{
errorList.Add(new InstanceIdPath() { Id = item.Id, Path = path });
errorList.Add(new InstanceIdPath() { Id = item.InstanceId, Path = path });
Log.Logger.Error(ex, $"StudyMaskImage Error for InstanceIdList Path:{path} {ex.Message}");
}

View File

@ -185,7 +185,9 @@ namespace IRaCIS.Core.Application.Service
CreateMap<ImageMarkNoneDicomStudyBasicInfo, NoneDicomStudyBasicInfo>();
CreateMap<DicomInstance, DownloadDicomInstanceDto>()
.ForMember(d => d.InstanceId, u => u.MapFrom(s => s.Id));
}
}

View File

@ -129,8 +129,8 @@ namespace IRaCIS.Core.Application.Service
public async Task<IResponseOutput> MaskImage()
{
var sourceDir = @"D:\images\11\像素匿名\隐私信息2&测量值\08\08017\基线V1\ST01371_1970-01-01_US\IMAGE";
var targetDir = @"D:\images\11\像素匿名\隐私信息2&测量值\08\08017\基线V1\ST01371_1970-01-01_US\IMAGE\after";
var sourceDir = @"C:\work\gitea\irc-netcore-api\DownloadImage";
var targetDir = @"C:\work\gitea\irc-netcore-api\DownloadImage\after";
Directory.CreateDirectory(targetDir);
var regions = new[]