概述

C#开源的DICOM server.支持影像处理、影像归档、影像管理、影像传输和影像浏览功能。开源代码可学习地方很多。

官方网站:http://www.clearcanvas.ca

building ImageViewer 的代码,

1、打开ImageViewer.sln 在 /Trunk/ImageViewer 用VS2008编译它.

2、运行ClearCanvas.Desktop.Executable Bin\debug 或Bin\Release下的项目.

  1. 编译通过ImageServer.sln 在 /Trunk/ImageServer
  2. 修改 connectionStringsImageServer_Shreds_dist.config 的user 和 password 在你安装了ImageServer数据库后.
  3. 编辑/Trunk/ImageServer/Executable/Logging.config 的ConnectionString 的 user 和 password .
  4. 编译通过这个项目
  5. 开启 ClearCanvas.ImageServer.ShredHostService ,运行里面的wcf server,可以在Bin\Log 看到开启后的日志.

结果如下

运行 ClearCanvas.Desktop.Executable 的结果如下

测试往Server加入.dcm文件的代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
[TestFixture]
    public class ScuTests : AbstractTest
    {
        [TestFixtureSetUp]
        public void Init()
        {
            _serverType = TestTypes.Receive;
        }
 
        [TestFixtureTearDown]
        public void Cleanup()
        {
        }
 
        TestTypes _serverType;
 
        public IDicomServerHandler ServerHandlerCreator(DicomServer server, ServerAssociationParameters assoc)
        {
            return new ServerHandler(this, _serverType);
        }
 
        private StorageScu SetupScu()
        {
            StorageScu scu = new StorageScu("TestAe", "AssocTestServer", "localhost", 104);
 
            IList<DicomAttributeCollection> list = SetupMRSeries(4, 2, DicomUid.GenerateUid().UID);
 
            foreach (DicomAttributeCollection collection in list)
            {
                DicomFile file = new DicomFile("test", new DicomAttributeCollection(), collection);
                file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                file.MediaStorageSopClassUid = SopClass.MrImageStorage.Uid;
                file.MediaStorageSopInstanceUid = collection[DicomTags.SopInstanceUid].ToString();
 
                scu.AddStorageInstance(new StorageInstance(file));
            }
 
            return scu;
        }
 
        [Test]
        public void ScuAbortTest()
        {
            int port = 2112;
 
            /* Setup the Server */
            ServerAssociationParameters serverParameters = new ServerAssociationParameters("AssocTestServer", new IPEndPoint(IPAddress.Any, port));
            byte pcid = serverParameters.AddPresentationContext(SopClass.MrImageStorage);
            serverParameters.AddTransferSyntax(pcid, TransferSyntax.ExplicitVrLittleEndian);
            serverParameters.AddTransferSyntax(pcid, TransferSyntax.ExplicitVrBigEndian);
            serverParameters.AddTransferSyntax(pcid, TransferSyntax.ImplicitVrLittleEndian);
 
            _serverType = TestTypes.Receive;
            DicomServer.StartListening(serverParameters, ServerHandlerCreator);
 
            StorageScu scu = SetupScu();
 
            IList<DicomAttributeCollection> list = SetupMRSeries(4, 2, DicomUid.GenerateUid().UID);
 
            foreach (DicomAttributeCollection collection in list)
            {
                DicomFile file = new DicomFile("test",new DicomAttributeCollection(),collection );
                file.TransferSyntax = TransferSyntax.ExplicitVrLittleEndian;
                file.MediaStorageSopClassUid = SopClass.MrImageStorage.Uid;
                file.MediaStorageSopInstanceUid = collection[DicomTags.SopInstanceUid].ToString();
 
                scu.AddStorageInstance(new StorageInstance(file));
            }
 
            scu.ImageStoreCompleted += delegate(object o, StorageInstance instance)
                                        {
                                            // Test abort
                                            scu.Abort();
                                        };
 
            scu.Send();
            scu.Join();
 
            Assert.AreEqual(scu.Status, ScuOperationStatus.NetworkError);
 
            // StopListening
            DicomServer.StopListening(serverParameters);
        }
    }

如果直接是filePath的话也可以这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class ImageStoreDAL
{
    private ConnectModel _connectModel;
 
    public ImageStoreDAL(ConnectModel connectModel)
    {
        _connectModel = connectModel;
    }
 
    public ConnectModel ConnectModelInstance
    {
        get { return _connectModel; }
        set { _connectModel = value; }
    }
 
    private StorageScu SetupScu(string filePath)
    {
        StorageScu scu = new StorageScu(_connectModel.ClientAETitle, _connectModel.RemoteAE, _connectModel.RemoteHost, _connectModel.RemotePort);
        DicomFile file = new DicomFile(filePath);
        scu.AddStorageInstance(new StorageInstance(file));
        return scu;
    }
 
    public ScuOperationStatus ImageStoreByFilePath(string filePath)
    {
        StorageScu scu = SetupScu(filePath);
        scu.Send();
        return scu.Status;
    }
}

ClearCanvas DICOM 开发系列 一的更多相关文章

  1. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  2. 【微信小程序开发•系列文章六】生命周期和路由

    这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...

  3. iOS开发系列文章(持续更新……)

    iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...

  4. iOS开发系列--App扩展开发

    概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...

  5. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...

  6. iOS开发系列--通知与消息机制

    概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...

  7. iOS开发系列--数据存取

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...

  8. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  9. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

随机推荐

  1. join和setdaemon()初探

    join()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(),那么主线程A会在调用的地方等待,直到子线程B完成操作后,才可以接着往下执行,那么在调用这个线程时可以使用被调用线程 ...

  2. Redis学习——ae事件处理源码分析

    0. 前言 Redis在封装事件的处理采用了Reactor模式,添加了定时事件的处理.Redis处理事件是单进程单线程的,而经典Reator模式对事件是串行处理的.即如果有一个事件阻塞过久的话会导致整 ...

  3. Hibernate与Mybatis的概念区别

    首先简单介绍下两者的概念: Hibernate :Hibernate 是当前最流行的ORM框架,对数据库结构提供了较为完整的封装. Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力 ...

  4. spring boot入门例子

    最近学习spring boot,总结一下入门的的基础知识 1新建maven项目,修改pom.xml <project xmlns="http://maven.apache.org/PO ...

  5. jQuery 根据城市时区,选择对应的即时时间

    我们的CRM系统中,下面是用jQuery 做了个时区小插件 如图: // 时区城市//$(function(){//所有城市和时间静态输出//var cityID = 170; //中国,北京//va ...

  6. java 递归获取一个目录下的所有文件路径

    还是日志的问题,log4j生成的日志文件,自动保存到月份所在的文件夹中,需要获取到所有的日志文件,包括文件夹 private List<String> ergodic(File file, ...

  7. Jetty多Connector

    有时候想要启动两个端口,或者通过一个Jetty server提供多个不同服务,比如说使用8080来指定默认访问端口,使用8433指定https访问端口等等,此时就可以通过创建多个Connector来解 ...

  8. 【采集层】Kafka 与 Flume 如何选择--转自悟性的博文

    [采集层]Kafka 与 Flume 如何选择 收藏 悟性 发表于 2年前 阅读 23167 收藏 16 点赞 4 评论 1 摘要: Kafka, Flume 采集层 主要可以使用Flume, Kaf ...

  9. java的集合框架最全详解

    java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...

  10. 将Ubuntu 15.10升级到Ubuntu 16.04

    Ubuntu 16.04 LTS 代号为 Xenial Xerus,其最终版将于 2016 年 4 月 21 日正式发布,Ubuntu16.04 将是非常受欢迎的开源操作系统 Ubuntu 的第 6 ...