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.
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