Search code examples
c#dicomfo-dicom

Fo-dicom code compiling but not executing


I am trying following code to convert a dicom file to jpeg:

using System;
using System.IO;
using System.Drawing; 
using Dicom.Imaging; 

class RnReadDicom{
    public static void Main(string[] args){
        string fileName = "33141578.dcm"; 
        var image = new DicomImage(fileName);
        image.RenderImage().AsSharedBitmap().Save(@"test.jpg");
        }}

I am compiling it with following command:

$ mcs a.cs -r:Dicom.Core.dll -r:Dicom.Native.dll -r:System.Drawing 

The code compiles without any error but on running the exe file, it gives following error:

$ ./a.exe 

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'Dicom.DicomEncoding' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object
  at Dicom.IO.IOManager.get_BaseEncoding () [0x00000] in <4b7c269b3e704f3f83dd85bb2721c76a>:0 
  at Dicom.DicomEncoding..cctor () [0x00000] in <4b7c269b3e704f3f83dd85bb2721c76a>:0 
   --- End of inner exception stack trace ---
  at Dicom.Imaging.DicomImage..ctor (System.String fileName, System.Int32 frame) [0x00000] in <4b7c269b3e704f3f83dd85bb2721c76a>:0 
  at RnReadDicom.Main (System.String[] args) [0x00006] in <5c119b113a6e4d4b8058662dd31bab14>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: The type initializer for 'Dicom.DicomEncoding' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object
  at Dicom.IO.IOManager.get_BaseEncoding () [0x00000] in <4b7c269b3e704f3f83dd85bb2721c76a>:0 
  at Dicom.DicomEncoding..cctor () [0x00000] in <4b7c269b3e704f3f83dd85bb2721c76a>:0 
   --- End of inner exception stack trace ---
  at Dicom.Imaging.DicomImage..ctor (System.String fileName, System.Int32 frame) [0x00000] in <4b7c269b3e704f3f83dd85bb2721c76a>:0 
  at RnReadDicom.Main (System.String[] args) [0x00006] in <5c119b113a6e4d4b8058662dd31bab14>:0 

Where is the problem and how can it be solved? Thanks for your help.

Edit: I am having similar problem with another library for which I have posted another question. This is using a different library and the error is also different. I suspect answers to these questions will be different hence these are not duplicate question. Moreover, the other question does not have any answer yet.


Solution

  • This is probably due to the garbage collector destroying the image object. The Bitmap only contains a reference to the pixel data of the image to save space.

    This has been described here before: C# System.Drawing.Image.get_Width() throws exception on WinForms form is maximized

    To solve this, use it as this:

    var image = new DicomImage(fileName);
    image.RenderImage().AsClonedBitmap().Save(@"test.jpg");
    

    By cloning, a real copy of the pixel data is performed.

    However, it could be sometimes even trickier: If you e. g. use .NET Core as a starting project and the library, which references fo-dicom uses .NET Standard, you have to add either of these to the start of your program:

        TranscoderManager.SetImplementation(new MonoTranscoderManager()); // limited codecs, but full .NET Core, runs on Linux. Or:
        TranscoderManager.SetImplementation(new DesktopTranscoderManager()); // loads also native dlls, runs on Windows
    
        ImageManager.SetImplementation(new RawImageManager()); // if you need .NET Core, you only have byte arrays
        ImageManager.SetImplementation(new WinFormsImageManager()); //if you run Windows and have GDI
    
        NetworkManager.SetImplementation(new DesktopNetworkManager()); // if you want to run dicom services