How to Use fo-dicom to exract multi-frames to multi-files

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.

January 28, 2026