DICOM 测试工具

一个DICOM测试工具。

引用了 fo-dicom 。fo-dicom 算是比较好用的,我的另外一个项目也是用了它。

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dicom;
using Dicom.Log;
using Dicom.Network;
using Dicom.Serialization;
using Newtonsoft.Json;

namespace DicomUtils
{

    public delegate void CStoreRequestHandler(TDicomServer Server, TDicomService service, string studyuid, string instuid, string tag, ref string fileid, ref string filename);
    public delegate void CStoreFileSavedHandler(TDicomServer Server, TDicomService service, string studyuid, string instuid, string tag, string fileid, string filename);
    public delegate void CFindHandler(TDicomServer Server, TDicomService service, string json,ref DataTable dt);

    public class TDicomServer
    {
        public IDicomServer Server = null;
        public ServerConfig Config = null;
        public List<TLogItem> Log = new List<TLogItem>();
        public void Start()
        {
            wirtelog("Server "+ "Start");
            Server = DicomServer.Create<TDicomService>(Config.Port, userState: this);

        }
        public void Stop()
        {
            if (Server != null)
            {
                wirtelog("Server " + "Stop");
                Server.Stop();
                Server.Dispose();
                Server = null;
            }

        }
        public event CStoreRequestHandler EventCStoreRequest;

        public virtual void OnCStoreRequest(TDicomService service,string studyuid, string instuid, string tag, ref string fileid, ref string filename)
        {
            if (filename == "")
            {
                string dir =get_storge_dir();
                string fn = System.IO.Path.Combine(dir, studyuid, instuid + ".dcm");
                filename = fn;

            }
            wirtelog("OnCStoreRequest " + filename);
            if (EventCStoreRequest != null)
            {
                EventCStoreRequest(this, service, studyuid, instuid, tag, ref fileid, ref filename);
            }
        }
        public event CStoreFileSavedHandler EventCStoreFileSaved;
        public virtual void OnCStoreFileSaved(TDicomService service, string studyuid, string instuid, string tag, string fileid, string filename)
        {
            wirtelog("OnCStoreFileSaved " + filename);
            string fn_json = System.IO.Path.ChangeExtension(filename,".json");
            System.IO.File.WriteAllText(fn_json, tag);
            if (EventCStoreFileSaved != null)
            {
                EventCStoreFileSaved(this, service, studyuid, instuid, tag, fileid, filename);
            }
        }
        public event CFindHandler EventCFind;
        public virtual void OnCFindRequest(TDicomService service, DicomDataset request, string json, List<DicomDataset> list)
        {
            wirtelog("OnCFindRequest " + json);
            if (EventCFind != null)
            {
                DataTable dt = null;
                EventCFind(this, service, json,ref dt);
                if (dt != null)
                {
                    List<WorklistItem> worklists = WorklistHandler.dt2worklists(dt);
                    List<DicomDataset> data= WorklistHandler.Worklist2DataSet(request,worklists);
                    list.AddRange(data);
                }
            } 
        }
        public void wirtelog(string msg)
        {
            lock (Log)
                try
                {

                    if (Log.Count > 1000)
                    {
                        Log.RemoveRange(0,500);
                    }
                    Log.Add(TLogItem.new_item(msg));
                }
                catch
                {

                } 
        }
        public string get_storge_dir()
        {
            return Config.get_storge_dir();
        }
    }



    public class TDicomService : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCFindProvider, IDicomCMoveProvider, IDicomCGetProvider, IDicomCEchoProvider
    {
        private static readonly DicomTransferSyntax[] AcceptedTransferSyntaxes = new DicomTransferSyntax[]
        {
               DicomTransferSyntax.ExplicitVRLittleEndian,
               DicomTransferSyntax.ExplicitVRBigEndian,
               DicomTransferSyntax.ImplicitVRLittleEndian
        };

        private static readonly DicomTransferSyntax[] AcceptedImageTransferSyntaxes = new DicomTransferSyntax[]
        {
               // Lossless
               DicomTransferSyntax.JPEGLSLossless,
               DicomTransferSyntax.JPEG2000Lossless,
               DicomTransferSyntax.JPEGProcess14SV1,
               DicomTransferSyntax.JPEGProcess14,
               DicomTransferSyntax.RLELossless,
               // Lossy
               DicomTransferSyntax.JPEGLSNearLossless,
               DicomTransferSyntax.JPEG2000Lossy,
               DicomTransferSyntax.JPEGProcess1,
               DicomTransferSyntax.JPEGProcess2_4,
               // Uncompressed
               DicomTransferSyntax.ExplicitVRLittleEndian,
               DicomTransferSyntax.ExplicitVRBigEndian,
               DicomTransferSyntax.ImplicitVRLittleEndian
        };

        public TDicomService(INetworkStream stream, Encoding fallbackEncoding, Logger log)
            : base(stream, fallbackEncoding, log)
        {


        }
        public TDicomServer GetSCPServer()
        {
            return (TDicomServer)UserState;
        }
        public void wirtelog(string msg)
        {
            TDicomServer Server = GetSCPServer();
            Server.wirtelog(msg);

        }
        public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
        {
            wirtelog("OnReceiveAssociationRequestAsync  IP:" + association.RemoteHost + " PORT:" + association.RemotePort.ToString() + " AE:" + association.CalledAE);

            TDicomServer Server = GetSCPServer();
            if (!Server.Config.isAllowAE(association.CalledAE))
            {
                wirtelog("SendAssociationRejectAsync  IP:" + association.RemoteHost + " PORT:" + association.RemotePort.ToString() + " AE:" + association.CalledAE);

                return SendAssociationRejectAsync(
                    DicomRejectResult.Permanent,
                    DicomRejectSource.ServiceUser,
                    DicomRejectReason.CalledAENotRecognized);
            }

            foreach (var pc in association.PresentationContexts)
            {
                if (pc.AbstractSyntax == DicomUID.Verification
                  || pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelFind
                  || pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelMove
                  || pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelFind
                  || pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelMove

                  || pc.AbstractSyntax == DicomUID.ModalityWorklistInformationModelFind
                  || pc.AbstractSyntax == DicomUID.ModalityPerformedProcedureStep
                  || pc.AbstractSyntax == DicomUID.ModalityPerformedProcedureStepNotification
                  || pc.AbstractSyntax == DicomUID.ModalityPerformedProcedureStepRetrieve

                  )
                {
                    pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
                }

                if (pc.AbstractSyntax == DicomUID.Verification) pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
                else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None) pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes);
            }

            return SendAssociationAcceptAsync(association);
        }

        public Task OnReceiveAssociationReleaseRequestAsync()
        {
            wirtelog("OnReceiveAssociationReleaseRequestAsync");
            return SendAssociationReleaseResponseAsync();
        }

        public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason)
        {
            wirtelog("OnReceiveAbort  IP:" + source.ToString() + " reason:" + reason.ToString());

        }

        public void OnConnectionClosed(Exception exception)
        {
            if (exception != null)
            {
                wirtelog("OnConnectionClosed  exception:" + exception.ToString());
            }
            else
            {
                wirtelog("OnConnectionClosed");
            }
        }
    
        public DicomCStoreResponse OnCStoreRequest(DicomCStoreRequest request)
        {
            TDicomServer Server = GetSCPServer();

            string studyUid = request.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID);
            string instUid = request.SOPInstanceUID.UID;
            wirtelog("OnCStoreRequest  studyUid:" + studyUid + " instUid:" + instUid);
            string tag = "";
            if (request.HasDataset)
                tag=Pub.DicomDataset2json(request.Dataset); 
            string filename = "";
            string fileid = "";
            Server.OnCStoreRequest(this, studyUid, instUid, tag, ref fileid, ref filename);
            string dir = System.IO.Path.GetDirectoryName(filename);
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);

            request.File.Save(filename);
            Server.OnCStoreFileSaved(this, studyUid, instUid, tag, fileid, filename);

            return new DicomCStoreResponse(request, DicomStatus.Success);

        }

        public void OnCStoreRequestException(string tempFileName, Exception e)
        {
            wirtelog("OnCStoreRequest  tempFileName:" + tempFileName + " exception:" + e.Message);
        }

        public DicomCEchoResponse OnCEchoRequest(DicomCEchoRequest request)
        {
            wirtelog("OnCEchoRequest  MessageID:" + request.MessageID);
            return new DicomCEchoResponse(request, DicomStatus.Success);
        }

        public IEnumerable<DicomCFindResponse> OnCFindRequest(DicomCFindRequest request)
        {
            wirtelog("OnCFindRequest  request:" + request.Type.ToString());
            string json = "";
            if (request.HasDataset)
                json =Pub.DicomDataset2json(request.Dataset);
            TDicomServer Server = GetSCPServer();
            List<DicomCFindResponse> responses = new List<DicomCFindResponse>();
            List<DicomDataset> list = new List<DicomDataset>();
            Server.OnCFindRequest(this, request.Dataset,json, list);
            foreach (DicomDataset result in list)
            {
                responses.Add(new DicomCFindResponse(request, DicomStatus.Pending) { Dataset = result });
            }
            responses.Add(new DicomCFindResponse(request, DicomStatus.Success));
            return responses;
        }

        public IEnumerable<DicomCMoveResponse> OnCMoveRequest(DicomCMoveRequest request)
        {
            wirtelog("OnCMoveRequest  request:" + request.Type.ToString());
            throw new NotImplementedException();
        }

        public IEnumerable<DicomCGetResponse> OnCGetRequest(DicomCGetRequest request)
        {
            wirtelog("OnCGetRequest  request:" + request.Type.ToString());
            throw new NotImplementedException();
        }
    }

    public class TLogItem
    {
        public Int64 id = get_new_id();
        public DateTime time = DateTime.Now;
        public string msg = "";
        public static Int64 last_id = 0;
        public static Int64 get_new_id()
        {
            last_id = last_id + 1;
            return last_id;
        }
        public static TLogItem new_item(string msg)
        {
            TLogItem i = new TLogItem();
            i.msg = msg;
            return i;
        }
    } 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月巴月巴白勺合鸟月半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值