c#: how to read parts of a file? (DICOM)

后端 未结 4 1769
[愿得一人]
[愿得一人] 2020-12-14 21:55

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

相关标签:
4条回答
  • 2020-12-14 22:27

    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
            }
    
    0 讨论(0)
  • 2020-12-14 22:29

    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.

    0 讨论(0)
  • 2020-12-14 22:31

    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;
            }
    
        }
    
    0 讨论(0)
  • 2020-12-14 22:40

    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?

    • Open as binary file, using File.OpenRead
    • Seek to position 128 and read 4 bytes into the array and compare it againts byte[] value for DICM. You can use ASCIIEncoding.GetBytes() for that

    How do I continue to parse the file reading the other parts of the data?

    • Continue reading the file using Read or ReadByte using the FileStream object handle that you have earlier
    • Use the same method like above to do your comparison.

    Dont forget to close and dispose the file.

    0 讨论(0)
提交回复
热议问题