c#:如何读取文件的各个部分? (DICOM)
我想在C#中读取DICOM文件。 我不想做任何花哨的事情,我现在只想知道如何读取元素,但首先我真的想知道如何读取标题以查看是否是有效的DICOM文件 。
它由二进制数据元素组成。 前128个字节未使用(设置为零),后跟字符串’DICM’。 接下来是标题信息,它被组织成组。
一个示例DICOM标头
前128个字节:未使用的DICOM格式。 其次是人物'D','我','C','M' 其次是额外的标题信息,例如: 0002,0000,文件元素组Len:132 0002,0001,文件元信息版本:256 0002,0010,传输语法UID:1.2.840.10008.1.2.1。 0008,0000,识别群长:152 0008,0060,形态:MR 0008,0070,制造商:MRIcro
在上面的示例中,标题被组织成组。 组0002hex是文件元信息组,其包含3个元素:一个定义组长度,一个存储文件版本,它们存储传输语法。
问题
- 如何通过检查128字节前导码后面的“D”,“I”,“C”,“M”字符来读取头文件并validation它是否是DICOM文件?
- 如何继续解析读取数据其他部分的文件?
像这样的东西应该读取文件,它的基本并不处理所有情况,但它将是一个起点:
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 ; }
代码实际上没有尝试并考虑到编码数据的传输语法可以在组2元素之后改变,它也不会尝试对读入的实际值做任何事情。
快速谷歌搜索带来了三个DICOM C#库:
- openDICOM.NET
- DICOM#
- MDCM
以下是C#中的示例: http : //www.codeproject.com/KB/graphics/dicomImageViewer.aspx
只是一些假的
如何通过检查128字节前导码后面的“D”,“I”,“C”,“M”字符来读取头文件并validation它是否是DICOM文件?
- 使用File.OpenRead以二进制文件打开
- 寻找位置128并将4个字节读入数组并再次比较DICM的byte []值。 您可以使用ASCIIEncoding.GetBytes()
如何继续解析读取数据其他部分的文件?
- 使用您之前使用的FileStream对象句柄继续使用Read或ReadByte读取文件
- 使用与上面相同的方法进行比较。
别忘了关闭并处理文件。
你也可以这样使用。
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 }
取自Evil Dicom库中的EvilDicom.Helper.DicomReader:
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 DICM 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; } }
- WPF DependencyObject调用线程exception
- 在后台工作程序中暂停/恢复循环
- Visual Studio设计器中的抽象通用UserControlinheritance
- 在MVVM应用程序中切换ViewModel时出现BindingExpression路径错误
- 在Visual Studio中安装DataTable Jquery插件
- 有什么能比Concurrent集合更好地解决这个multithreading场景
- Cql批量复制/插入C#
- 如何使用DataContractJsonSerializer反序列化字典?
- Dictionary.Keys返回的KeyCollection上的操作有多快? (。净)