Efficiently Export Media Contents from Data Sets

A Data Set can contain one or more media streams in the form of images or video. While the LEADTOOLS toolkit provides many options to access these media streams and process or convert them, these methods can be slow and memory-consuming when the stored media is large (e.g. 2 GB). The Following tutorial demonstrates how to directly access media streams and extract them to disk. For more information about data sets, refer to WorkingWithDataSets.

Quickly access and export stored media from a data set:

class Program{ 
   static void ExportMedia(string filename, string outputfolder) 
   { 
      using (var ds = new DicomDataSet()) 
      { 
         Console.WriteLine("\n---------------------\n"); 
         Console.WriteLine(filename); 
              
         ds.Load(filename, DicomDataSetLoadFlags.None); 
              
         string transfersyntax = GetStringValue(ds, DicomTag.TransferSyntaxUID); 
         Console.WriteLine(transfersyntax); 
              
         var pixelDataElement = ds.FindFirstElement(null, DicomTag.PixelData, false); 
             
         if (null == pixelDataElement) 
         { 
            throw new Exception("Missing [DicomTag.PixelData] element, dataset has no image or video."); 
         } 
              
         var compressed = IsCompressed(transfersyntax); 
         var childrenCount = GetChildrenCount(ds, pixelDataElement); 
              
         // uncompressed data is stored directly to pixelDataElement 
         // data can contain one or more frames 
         if (!compressed && childrenCount == 0) 
         { 
            if (pixelDataElement.Length > 0) 
            { 
               Console.WriteLine("Uncompressed bitmap (will not be exported)"); 
               Console.WriteLine("elem:\tOffset: " + pixelDataElement.ValueOffset + " \tLength: " + pixelDataElement.ValueLength); 
               //Uncompressed data has no headers. Therefore, export it to a single file and then split it into a number of frames. 
               //You need a proper writer to provide bitmap headers. It is best to use ds.GetImage().                   
           } 
            else 
            { 
               throw new Exception("[DicomTag.PixelData] element is empty"); 
            } 
         } 
         else if (compressed) 
         { 
            Console.WriteLine("Compressed data"); 
              
            var itemElement = ds.GetChildElement(pixelDataElement, true); 
            int index = 0; 
              
            while (itemElement != null) 
            { 
               if (itemElement.Length > 0) 
               { 
                  Console.WriteLine("elem:\tOffset: " + itemElement.ValueOffset + " \tLength: " + itemElement.ValueLength); 
                  if (itemElement.ValueLength > Int32.MaxValue) 
                 { 
                     throw new Exception("Stream is too big."); 
                  } 
                  Export(filename, outputfolder, index, transfersyntax, itemElement.ValueOffset, (Int32)itemElement.ValueLength); 
               } 
               else if (index > 0)//first item is always empty 
               { 
                  throw new Exception("Missing [DicomTag.Item] element."); 
               } 
              
               itemElement = ds.GetNextElement(itemElement, true, true); 
               ++index; 
            } 
         } 
         else 
         { 
            throw new Exception("Invalid dataset."); 
         } 
              
        Console.WriteLine("\n---------------------\n"); 
      } 
   } 
              
   static string GetStringValue(DicomDataSet ds, long tag) 
   { 
      DicomElement element; 
      bool tree = true; 
              
      element = ds.FindFirstElement(null, tag, tree); 
      if (element != null) 
      { 
         if (ds.GetElementValueCount(element) > 0) 
         { 
            return ds.GetConvertValue(element); 
         } 
      } 
              
      return ""; 
  } 
              
   static int GetChildrenCount(DicomDataSet ds, DicomElement element) 
   { 
      int count = 0; 
              
      var itemElement = ds.GetChildElement(element, true); 
             
      while (itemElement != null) 
      { 
         ++count; 
         itemElement = ds.GetNextElement(itemElement, true, true); 
      } 
      Console.WriteLine("sub items: " + count); 
      return count; 
   } 
              
   private static void CopyStream(Stream source, Stream target, Int32 size) 
   { 
      const Int32 bufferSize = 1024 * 64; 
     var buffer = new byte[bufferSize]; 
      int bytesRead = 0; 
      do 
      { 
         bytesRead = source.Read(buffer, 0, Math.Min(size, bufferSize)); 
         if (bytesRead > 0) 
            target.Write(buffer, 0, bytesRead); 
         size -= bytesRead; 
      } 
      while (bytesRead > 0); 
   } 
              
   static void Export(string filename, string outputfolder, int index, string transfersyntax, long offset, Int32 size) 
   { 
      string targetfilename = Path.Combine(outputfolder, Path.GetFileName(filename) + "_" + index + "." + GetProperExtension(transfersyntax)); 
      Directory.CreateDirectory(outputfolder); 
      using (var target = new FileStream(targetfilename, FileMode.Create)) 
      { 
         using (var src = new FileStream(filename, FileMode.Open)) 
        { 
            src.Seek(offset, SeekOrigin.Begin); 
            CopyStream(src, target, size); 
         } 
      } 
   } 
              
   static bool IsCompressed(string transfersyntax) 
   { 
      if (transfersyntax == DicomUidType.ImplicitVRLittleEndian || 
         transfersyntax == DicomUidType.ExplicitVRLittleEndian || 
         transfersyntax == DicomUidType.ExplicitVRBigEndian) 
      { 
         return false; 
      } 
      else 
      { 
         return true; 
      } 
  } 
              
   static string GetProperExtension(string transfersyntax) 
   { 
      switch (transfersyntax) 
      { 
         case DicomUidType.MPEG2MainProfileHighLevel: return "mpeg"; 
         case DicomUidType.MPEG2MainProfileMainLevel: return "mpeg"; 
         case DicomUidType.Mpeg4AvcH264BdCompatibleHighProfileLevel_4_1: return "mp4"; 
         case DicomUidType.Mpeg4AvcH264HighProfileLevel4_1: return "mp4"; 
         case DicomUidType.JPEG2000: return "j2k"; 
         case DicomUidType.JPEG2000LosslessOnly: return "j2k"; 
         case DicomUidType.JPEG2000Part2MultiComponentImageCompression: return "j2k"; 
         case DicomUidType.JPEG2000Part2MultiComponentImageCompressionLosslessOnly: return "j2k"; 
         case DicomUidType.JPEGBaseline1: return "jpg"; 
         case DicomUidType.JPEGExtended2_4: return "jpg"; 
         case DicomUidType.JPEGExtended3_5: return "jpg"; 
         case DicomUidType.JPEGExtendedHier16_18: return "jpg"; 
         case DicomUidType.JPEGExtendedHier17_19: return "jpg"; 
        case DicomUidType.JPEGFullHier24_26: return "jpg"; 
         case DicomUidType.JPEGFullHier25_27: return "jpg"; 
         case DicomUidType.JPEGFullNonhier10_12: return "jpg"; 
         case DicomUidType.JPEGFullNonhier11_13: return "jpg"; 
         case DicomUidType.JPEGLosslessHierProcess28: return "jpg"; 
         case DicomUidType.JPEGLosslessHierProcess29: return "jpg"; 
         case DicomUidType.JPEGLosslessNonhier14: return "jpg"; 
         case DicomUidType.JPEGLosslessNonhier14B: return "jpg"; 
         case DicomUidType.JPEGLosslessNonhier15: return "jpg"; 
         case DicomUidType.JPEGLSLossless: return "jpg"; 
         case DicomUidType.JPEGLSLossy: return "jpg"; 
         case DicomUidType.JPEGSpectralHier20_22: return "jpg"; 
         case DicomUidType.JPEGSpectralHier21_23: return "jpg"; 
         case DicomUidType.JPEGSpectralNonhier6_8: return "jpg"; 
         case DicomUidType.JPEGSpectralNonhier7_9: return "jpg"; 
                       
         default: return "bin"; 
      } 
   } 
              
  static void Main(string[] args) 
  { 
     DicomEngine.Startup(); 
     ExportMedia(@"d:\image1.dcm", @"d:\exported"); 
     DicomEngine.Shutdown(); 
  } 
} 

Help Version 23.0.2024.3.4
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2024 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Imaging, Medical, and Document

Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.