I would like to read a DICOM file in C#. I don\'t want to do anything fancy, I just for now would like to know how to read in the elements, but first I would actually like
you can also use like this.
FileStream fs = File.OpenRead(path);
byte[] data = new byte[132];
fs.Read(data, 0, data.Length);
int b0 = data[0] & 255, b1 = data[1] & 255, b2 = data[2] & 255, b3 = data[3] & 255;
if (data[128] == 68 && data[129] == 73 && data[130] == 67 && data[131] == 77)
{
//dicom file
}
else if ((b0 == 8 || b0 == 2) && b1 == 0 && b3 == 0)
{
//dicom file
}
Something like this should read the file, its basic and doesn't handle all cases, but it would be a starting point:
public void ReadFile(string filename)
{
using (FileStream fs = File.OpenRead(filename))
{
fs.Seek(128, SeekOrigin.Begin);
if ((fs.ReadByte() != (byte)'D' ||
fs.ReadByte() != (byte)'I' ||
fs.ReadByte() != (byte)'C' ||
fs.ReadByte() != (byte)'M'))
{
Console.WriteLine("Not a DCM");
return;
}
BinaryReader reader = new BinaryReader(fs);
ushort g;
ushort e;
do
{
g = reader.ReadUInt16();
e = reader.ReadUInt16();
string vr = new string(reader.ReadChars(2));
long length;
if (vr.Equals("AE") || vr.Equals("AS") || vr.Equals("AT")
|| vr.Equals("CS") || vr.Equals("DA") || vr.Equals("DS")
|| vr.Equals("DT") || vr.Equals("FL") || vr.Equals("FD")
|| vr.Equals("IS") || vr.Equals("LO") || vr.Equals("PN")
|| vr.Equals("SH") || vr.Equals("SL") || vr.Equals("SS")
|| vr.Equals("ST") || vr.Equals("TM") || vr.Equals("UI")
|| vr.Equals("UL") || vr.Equals("US"))
length = reader.ReadUInt16();
else
{
// Read the reserved byte
reader.ReadUInt16();
length = reader.ReadUInt32();
}
byte[] val = reader.ReadBytes((int) length);
} while (g == 2);
fs.Close();
}
return ;
}
The code does not actually try and take into account that the transfer syntax of the encoded data can change after the group 2 elements, it also doesn't try and do anything with the actual values read in.
Taken from EvilDicom.Helper.DicomReader from the Evil Dicom library:
public static bool IsValidDicom(BinaryReader r)
{
try
{
//128 null bytes
byte[] nullBytes = new byte[128];
r.Read(nullBytes, 0, 128);
foreach (byte b in nullBytes)
{
if (b != 0x00)
{
//Not valid
Console.WriteLine("Missing 128 null bit preamble. Not a valid DICOM file!");
return false;
}
}
}
catch (Exception)
{
Console.WriteLine("Could not read 128 null bit preamble. Perhaps file is too short");
return false;
}
try
{
//4 DICM characters
char[] dicm = new char[4];
r.Read(dicm, 0, 4);
if (dicm[0] != 'D' || dicm[1] != 'I' || dicm[2] != 'C' || dicm[3] != 'M')
{
//Not valid
Console.WriteLine("Missing characters D I C M in bits 128-131. Not a valid DICOM file!");
return false;
}
return true;
}
catch (Exception)
{
Console.WriteLine("Could not read DICM letters in bits 128-131.");
return false;
}
}
Just some pseudologic
How to I read the header file and verify if it is a DICOM file by checking for the 'D','I','C','M' characters after the 128 byte preamble?
How do I continue to parse the file reading the other parts of the data?
Dont forget to close and dispose the file.