使用XML数据保存DICOM文件

时间:2019-10-04 20:15:28

标签: c# xml save load dicom

因此,目前我有一个程序,它接收DICOM file并对其进行解析。在解析过程中,程序将查看DICOM数据中的数据,并将其分配给Dictionary Entry。我的目标是通过数据编辑一些关键标签,然后将XML写入新的DICOM文件。但是,我很难弄清楚如何将所做的更改保存到新的DICOM文件中,这样我就可以拥有原始的和新编辑的DICOM文件。

private XmlDictionary ReadXML(string FileName)

{
    XmlSerializer xmls = new XmlSerializer(typeof(XmlDictionary));
    XmlDictionary xmldic = new XmlDictionary();

    XmlNodeList xn = null;
    FileInfo file = new FileInfo(FileName);
    if (!file.Exists)
    {
        return xmldic;
    }
    XmlDocument xdoc = new XmlDocument();
    try
    {
        xdoc.Load(FileName);
        xn = xdoc.SelectNodes("/Dictionary/Tag");
        xn.GetType();

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

    xmldic.xmlTag = new XmlTag[xn.Count];
    StreamReader sr = new StreamReader(FileName);

    xmldic = (XmlDictionary)xmls.Deserialize(sr);
    sr.Close();
    return xmldic;
}
public void LoadPrivateTags()
{
    DICOMViewer.Properties.Settings mySettings = new DICOMViewer.Properties.Settings();
    DirectoryInfo dir = new DirectoryInfo(Application.StartupPath);
    FileInfo[] files = dir.GetFiles("privatedata*.xml");
    for (int i = 0; i < files.Length; i++)
    {
        try
        {
            string filepath = files[i].FullName;
            XmlDictionary dic = ReadXML(filepath);
            if (dic.xmlTag != null)
            {
                for (int ilist = 0; ilist < dic.xmlTag.Length; ilist++)
                {
                    int group = Convert.ToInt32(dic.xmlTag[ilist].xmlGroup, 16);
                    int element = Convert.ToInt32(dic.xmlTag[ilist].xmlElement, 16);
                    string s = Wrapper.TagDescription((uint)((group<<16)+element));
                    if ((s != "Undefined")&&(mySettings.WarnOfDuplicates == true))
                    {
                        MessageBox.Show(string.Format("Element {0:X},{1:X} <{2}> seems to be in dictionary already.",group, element, s), "Duplicate Private Data");
                    }
                    Wrapper.AddDictionaryEntry(group, element,
                        dic.xmlTag[ilist].xmlVR, dic.xmlTag[ilist].xmlDescription,
                        dic.xmlTag[ilist].xmlValueMultiplicity);
                }
            }
        }
        catch
        {}
    }
}
public void openDcmFile(string filename)

{
    UseWaitCursor = true;
    ViewDCM form = new ViewDCM();
    form.MdiParent = this;
    form.Text = System.IO.Path.GetFileName(filename);

    DateTime startTime = DateTime.Now;

    DCM read = new DCM(filename);
    form.treeView1.Nodes.Add(read.GetNodes());
    form.treeView1.Sort();
    form.imageView1.GraphicsImage.BitmapList.Clear();
    form.splitContainer1.Panel1Collapsed = true;

    DateTime endTime = DateTime.Now;

    TimeSpan loadTime = endTime.Subtract(startTime);

    Bitmap[] img = read.GetImgs();




    if (img != null)
    {
        if (img.Length == 1)
        {
            form.imageView1.GraphicsImage.BitmapList.Add(img[0]);
            form.trackBar1.Visible = false;
        }
        else
        {
            form.imageView1.GraphicsImage.BitmapList.AddRange(img);
            form.trackBar1.Visible = true;
            form.trackBar1.Maximum = img.Length - 1;
            form.trackBar1.Minimum = 0;
            if (img.Length < 30) form.trackBar1.LargeChange = 1;
            else form.trackBar1.LargeChange = form.trackBar1.Maximum / 10;
        }
        form.splitContainer1.Panel1Collapsed = false;
    }
    else
    {
        form.Text += " --- No Image Data ";
    }
    form.imageView1.GraphicsImage.Brightness = 200;
    form.imageView1.GraphicsImage.InitialBrightness = 200;
    form.imageView1.GraphicsImage.Contrast = 50;
    form.imageView1.GraphicsImage.InitialContrast = 50;
    form.imageView1.GraphicsImage.ShowThickness = false;
    form.imageView1.GraphicsImage.ColorMode = CZM.CZMGraphics.GraphicsLib.Image.ImageColorMode.Pseuocolor;
    form.imageView1.GraphicsImage.Show = true;
    form.treeView1.ExpandAll();

    form.Show();

    //Application.DoEvents();
    form.imageView1.Refresh();
    UseWaitCursor = false;
}

这些是我用来读取DICOM并将其转换为XML的3个关键功能。我只需要一种将已编辑的XML保存到新的DICOM文件中的方法。

编辑: 我还使用这个DICOM类将文件中的所有数据放入表单树节点

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using GraphicsLib = CZM.CZMGraphics.GraphicsLib;
using CZM.Core.DCMLib;
using System.IO;

namespace DICOMViewer
{
    class DCM  
    {
        string _fileName;
        TreeNode RootNode;
        Hashtable m_hash;
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="filename"></param>
        public  DCM(string filename)
        {
            _fileName = filename;
        }

        /// <summary>
        /// Gets tags details
        /// </summary>
        /// <returns></returns>
        public TreeNode GetNodes()
        {
            RootNode = new TreeNode("DICOM Tags");
            try {
                m_hash = CZM.Core.DCMLib.DCMLIB.RetrieveDicom(_fileName);

                DateTime t1 = DateTime.Now;
                var fs = new FileStream(_fileName, FileMode.Open);
                Console.WriteLine("FS data: " + fs);
                var bbb = new BinaryReader(fs);
                Console.WriteLine("BBB data: " + bbb);
                var bb2 = bbb.ReadBytes((int)fs.Length);
                Console.WriteLine("BB2 data: " + bb2);
                DateTime t2 = DateTime.Now;
                Console.WriteLine("T2 data: " + t2);
                TimeSpan ts = t2.Subtract(t1);
                Console.WriteLine("T2 Cont. data: " + ts);

                int k = ts.Seconds;
                Console.WriteLine("K data: " + k);
            }
            catch { return RootNode; }
            RootNode.ForeColor = Color.Green;  
            foreach (DictionaryEntry de in m_hash)
            {
                GetValue(de);
                Console.WriteLine("DICTIONARY: " + de);
                Console.WriteLine("ROOTNODE IS " + RootNode.Nodes);
            }
            return RootNode; 
        }

        public void GetValue(DictionaryEntry de)
        {
            int key = (int)de.Key;
            Console.WriteLine("Get Value jey: " + key);
            int group = ((key >> 16) & 0xffff);
            Console.WriteLine("Get Value group " + group);
            int element = (key & 0xffff);
            Console.WriteLine("Get Value element: " + element);
            string groupstr = group.ToString("X4");
            Console.WriteLine("Get Value groupstr: " + groupstr);

            string elementstr = element.ToString("X4");
            Console.WriteLine("Get Value elementstr: " + elementstr);

            object value = de.Value;
            Console.WriteLine("Get Value of value: " + value);
            Console.WriteLine("Get Value of value as string: " + value.ToString());

            // Sequences handled here
            if (de.Value.GetType().ToString() == "System.Collections.ArrayList")
            {
                if (key == 0x7FE00010)
                {
                    return;
                }

                // DICOM Sequences are implemented with ArrayLists
                TreeNode GroupNode = new TreeNode(groupstr);
                ArrayList array = (ArrayList)de.Value;
                // Each Array in the List holds a hashtable
                for (int i = 0; i < array.Count; i++)
                {
                    Hashtable table = (Hashtable)array[i];
                    TreeNode SeqNode = new TreeNode(groupstr + elementstr + " , " + GetDescription(group, element));
                    Console.WriteLine("SeqNode --- : " + SeqNode);
                    SeqNode.ForeColor = Color.Green;
                    // Fill the sequence node with the stuff in the array element's hash
                    AddSubNode(table, groupstr, ref SeqNode);
                    GroupNode.Nodes.Add(SeqNode); // put sequence in group
                }

                bool addGrouptoRoot = true;
                // Either add the sequence to an existing node or create a new one
                foreach (TreeNode snode in RootNode.Nodes)
                {
                    if (snode.Text == GroupNode.Text) // if group node is already in root...
                    {
                        foreach (TreeNode child in GroupNode.Nodes)// copy the group's nodes to the root's group node
                        {
                            snode.Nodes.Add(child);
                            Console.WriteLine("Child of the SNode is: " + child);
                        }
                        addGrouptoRoot = false;
                        break;
                    }
                }
                // else, add the new group to the root
                if (addGrouptoRoot == true) 
                {
                    RootNode.Nodes.Add(GroupNode);
                    Console.WriteLine("GroupNode data: " + GroupNode);
                }
                return;
            }


            // Single data elements are handled here
            bool addnode = true;
            foreach (TreeNode snode in RootNode.Nodes)
            {
                if (snode.Text == groupstr) // If the group already exists in root set..put it in the existing node
                {
                    snode.Nodes.Add(groupstr + elementstr + " , " + GetDescription(group, element) + " : " + GetInfo(value));
                    Console.WriteLine("sNode in foreach: " + snode);
                    addnode = false;
                    break;
                }
            }
            if (addnode == true)
            {
                TreeNode snode = new TreeNode(groupstr);
                snode.Nodes.Add(groupstr + elementstr + " , " + GetDescription(group, element) + " : " + GetInfo(value));
                Console.WriteLine("sNode in true: " + snode);
                RootNode.Nodes.Add(snode);
                Console.WriteLine("RootNode Node in true: " + snode);
            }

        }

        string GetInfo(object obj)
        {
            if (obj is System.String)
            {
                Console.WriteLine("OBJECT DATA: " + obj.ToString());
                return obj.ToString();
            }


            if (obj is System.Single[])
            {
                Single[] arr = (Single[])obj;
                string str = "";
                foreach (Single value in arr)
                {
                    str += value.ToString() + ",";
                }
                return str;
            }

            return obj.ToString(); 
        }

        string GetDescription(int group,int element)
        {
            string str = DCMLIB.TagDescription((uint)(group << 16 | element));
            Console.WriteLine("str in GetDescription:  " + str);
            if (str == "Undefined") 
                return "Needs Private Data Definition - see help.";
            else
                return str;
        }
        string TagStr(int group, int element)
        {
            return group.ToString("X4") + element.ToString("X4");
        }

        void AddSubNode(Hashtable hash,string groupname,ref TreeNode sNode)
        {
            foreach (DictionaryEntry de in hash)
            {
                int key = (int)de.Key;
                Console.WriteLine("KEY: "+key);
                int group = ((key >> 16) & 0xffff);
                Console.WriteLine("group  " + group);
                int element = (key & 0xffff);
                Console.WriteLine("element:  " + element);
                string groupstr = group.ToString("X4");
                Console.WriteLine("groupstr " + groupstr);

                string elementstr = element.ToString("X4");
                Console.WriteLine("ElementStr " + elementstr);


                object value = de.Value;
                Console.WriteLine("VALUE: " + value);
                if (de.Value.GetType().ToString() == "System.Collections.ArrayList")
                {
                    if (key == 0x7FE00010)//(groupstr.ToLower() + elementstr.ToLower()) == "7fe00010")
                    {
                        return;
                    }
                    ArrayList array = (ArrayList)de.Value;
                    for (int i = 0; i < array.Count; i++)
                    {
                        TreeNode tNode = new TreeNode(key.ToString());
                        Hashtable table = (Hashtable)array[i];
                        AddSubNode(table, groupname, ref tNode);
                        sNode.Nodes.Add(tNode);
                        Console.WriteLine("sNode details " + sNode);
                    }
                }
                else
                    sNode.Nodes.Add(groupstr + elementstr + " , " + GetDescription(group, element) + " : " + GetInfo(value) );
            }
        }
        /// <summary>
        /// Gets bitmap details
        /// </summary>
        /// <returns></returns>
        public Bitmap[] GetImgs()
        {
            Bitmap[] bitmaps = null;
            int Width=0, Height=0, bitStored=0,Frames = 0;
            try
            {
                Width = (int)m_hash[0x00280011]; if (Width == 0) return null;
                Height = (int)m_hash[0x00280010]; if (Height == 0) return null;
                bitStored = (int)m_hash[0x00280101]; if (bitStored == 0) return null;
                object o = m_hash[0x00280008]; 
                if (o != null) //frames tag check
                Frames = Convert.ToInt32(o.ToString());
            }
            catch
            {
                return null;
            }

            // initial implementations of CDML could have frames = 0 or 1 for a single image
            // multi-frame storage uses frames correctly
            if ((Frames == 0) || (Frames == 1))
            {
                if (m_hash.Contains(0x7FE00010))
                {
                    byte[] imgbyte = ReadByte((byte[])m_hash[0x7FE00010], bitStored);
                    bitmaps = new Bitmap[1];
                    bitmaps[0] = GraphicsLib.BitmapUtility.CopyMonochromeBytesTo8bppIndexedBitmap(Width, Height, imgbyte);
                    return bitmaps;
                }
                return null;
            }
            else
            {
                if (m_hash.Contains(0x7FE00010))
                {
                    bitmaps = new Bitmap[Frames];
                    ArrayList arrayImg = (ArrayList)m_hash[0x7FE00010];
                    for (int i = 0; i < arrayImg.Count; i++)
                    {
                        if (bitStored == 24)
                        {
                            byte[] imgbyte = (byte[])arrayImg[i];
                            Bitmap bitmap = new Bitmap(Width, Height);   
                            GraphicsLib.BitmapUtility.Copy24bppBitmapToMonochromeBytes(bitmap,ref imgbyte);
                            bitmaps[i] = bitmap;
                        }
                        else
                        {
                            byte[] imgbyte = ReadByte((byte[])arrayImg[i], bitStored);
                            bitmaps[i] = GraphicsLib.BitmapUtility.CopyMonochromeBytesTo8bppIndexedBitmap(Width, Height, imgbyte);
                            bitmaps[i].RotateFlip(RotateFlipType.Rotate270FlipY);
                        }
                    }
                    return bitmaps; 
                }
                return null;
            }
        }

        //Converting value to  hexadecimal
        /// <summary>
        /// convert number to hex string of given length
        /// </summary>
        /// <param name="h"></param>
        /// <param name="l"></param>
        /// <returns></returns>
        //private string hex(int h, int l)
        //{
        //    return h.ToString("X");

        //}
        private byte[] ReadByte(byte[] pixel,int bits)
        {
            byte b1 = 0, b2 = 0, s = 0;
            byte[] singlePixel = new byte[pixel.Length];
            if (bits == 8)
            {
                return pixel;
            }
            if (bits <= 16)
            {
                int x = 0;
                for (int i = 0; i < pixel.Length; i += 2)
                {
                    b1 = pixel[i];
                    b2 = pixel[i + 1];
                    short val = (short)(b1 + (b2 * 256));
                    s = (byte)((val - short.MinValue) * byte.MaxValue / (short.MaxValue - short.MinValue));
                    singlePixel[x] = s;
                    x++;
                }
            }
            return singlePixel;
        }
    }

}

0 个答案:

没有答案