How to Use fo-dicom to Extract MultiFrames File to Multi DICOM Files For WebRenderer
Installing fo-dicom Dependencies
To begin, install the required fo-dicom packages using NuGet Package Manager in Visual Studio:
dotnet add package fo-dicom
dotnet add package fo-dicom.Codecs
dotnet add package fo-dicom.Imaging.ImageSharp
Extracting Multi-Frames to Multi-Files
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.Imaging.Codec;
using FellowOakDicom.IO.Buffer;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using DicomTransferSyntax = FellowOakDicom.DicomTransferSyntax;
namespace RemoveSomeTags
{
public static class MultiFramesExtrac
{
public static async Task<bool> ExtractMultiFramesToMultiFiles(string dicomFileIn, string dicomOutStr)
{
if (string.IsNullOrWhiteSpace(dicomFileIn) || string.IsNullOrWhiteSpace(dicomOutStr))
return false;
try
{
var dicomFile = await DicomFile.OpenAsync(dicomFileIn);
var ds = dicomFile.Dataset;
if (!ds.Contains(DicomTag.NumberOfFrames))
{
Console.WriteLine("No NumberOfFrames tag found.");
return false;
}
int numFrames = ds.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 1);
if (numFrames <= 1)
{
Console.WriteLine("No frames found. or single frame only.");
return false;
}
// Create PixelData(maybe encapsulated)
DicomPixelData pixelData = DicomPixelData.Create(ds, false);
IByteBuffer[] frameBuffers = Enumerable.Range(0, pixelData.NumberOfFrames)
.Select(i => pixelData.GetFrame(i))
.ToArray();
Directory.CreateDirectory(dicomOutStr);
var seriesUid = ds.GetSingleValueOrDefault(DicomTag.SeriesInstanceUID, DicomUID.Generate().UID);
var frames = frameBuffers.Length;
for (int i = 0; i < frames; i++)
{
var frameBuffer = frameBuffers[i];
var newDs = ds.Clone();
var newSopUid = DicomUID.Generate();
newDs.AddOrUpdate(DicomTag.SOPInstanceUID, newSopUid.UID);
newDs.AddOrUpdate(DicomTag.InstanceNumber, i + 1);
newDs.AddOrUpdate(DicomTag.NumberOfFrames, 1);
newDs.Remove(DicomTag.PixelData);
var newPixel = DicomPixelData.Create(newDs, true);
newPixel.AddFrame(frameBuffer);
var outFile = Path.Combine(dicomOutStr, $"{seriesUid}_{i + 1:D4}.dcm");
var newFile = new DicomFile(newDs)
{
FileMetaInfo =
{
MediaStorageSOPClassUID = dicomFile.FileMetaInfo.MediaStorageSOPClassUID,
MediaStorageSOPInstanceUID = newSopUid,
TransferSyntax = dicomFile.FileMetaInfo.TransferSyntax ??
pixelData.Syntax
}
};
await newFile.SaveAsync(outFile);
}
return true;
}
catch (Exception finalEx)
{
await Console.Error.WriteLineAsync("Unexpected error: " + finalEx);
return false;
}
}
}
}
Important Note
this code is a basic implementation and may not cover all possible scenarios or edge cases. It’s recommended to thoroughly test and modify the code according to your specific requirements.