概述
DICOM网络传输采用的是C/S模式,storescu/storescp主要是处理dicom文件的传输存储,具体概念请见博客
DICOM医学图像处理:DICOM网络传输
本文主要介绍dcm4che中是如何处理和实现storescp服务的
步骤
- 引入dcm4che的依赖jar包
- 设置(org.dcm4che3.net.Connection)连接的IP和端口
- 设置(org.dcm4che3.net.ApplicationEntity)AETitle的名称,服务类型和过滤器
- 启动service
引入依赖库
<dependency>
<groupId>org.dcm4che</groupId>
<artifactId>dcm4che-core</artifactId>
<version>5.21.0</version>
</dependency>
<dependency>
<groupId>org.dcm4che</groupId>
<artifactId>dcm4che-imageio</artifactId>
<version>5.21.0</version>
</dependency>
<dependency>
<groupId>org.dcm4che</groupId>
<artifactId>dcm4che-imageio-opencv</artifactId>
<version>5.21.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.dcm4che</groupId>
<artifactId>dcm4che-net</artifactId>
<version>5.21.0</version>
</dependency>
代码
package com.airking.dcm4che.dcm4cheTest;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.Tag;
import org.dcm4che3.data.VR;
import org.dcm4che3.io.DicomOutputStream;
import org.dcm4che3.net.ApplicationEntity;
import org.dcm4che3.net.Association;
import org.dcm4che3.net.Connection;
import org.dcm4che3.net.Device;
import org.dcm4che3.net.PDVInputStream;
import org.dcm4che3.net.Status;
import org.dcm4che3.net.TransferCapability;
import org.dcm4che3.net.pdu.PresentationContext;
import org.dcm4che3.net.service.BasicCEchoSCP;
import org.dcm4che3.net.service.BasicCStoreSCP;
import org.dcm4che3.net.service.DicomServiceException;
import org.dcm4che3.net.service.DicomServiceRegistry;
import org.dcm4che3.util.SafeClose;
public class Dcm2cheStoreSCP {
private final Device device = new Device("storescp");
private final ApplicationEntity ae = new ApplicationEntity("*");
private final Connection conn = new Connection();
private String storageDir = "D:/dicomFile/cacheData/"; //接收到dicom文件的存储目录
ExecutorService executorService = Executors.newCachedThreadPool();;
private final BasicCStoreSCP cstoreSCP = new BasicCStoreSCP("*") {
private static final String PART_EXT = ".part";
@Override
protected void store(Association as, PresentationContext pc,
Attributes rq, PDVInputStream data, Attributes rsp)
throws IOException {
try {
rsp.setInt(Tag.Status, VR.US, 0);
if (storageDir == null)
return;
String cuid = rq.getString(Tag.AffectedSOPClassUID);
String iuid = rq.getString(Tag.AffectedSOPInstanceUID);
String tsuid = pc.getTransferSyntax();
File file = new File(storageDir, iuid + PART_EXT);
try {
storeTo(as, as.createFileMetaInformation(iuid, cuid, tsuid),
data, file);
renameTo(as, file, new File(storageDir, iuid));
} catch (Exception e) {
//deleteFile(as, file);
file.delete();
throw new DicomServiceException(Status.ProcessingFailure, e);
}
} finally {
// sleep(as, responseDelays);
}
}
};
public Dcm2cheStoreSCP() {
device.setDimseRQHandler(createServiceRegistry());
device.addConnection(conn);
device.addApplicationEntity(ae);
ae.setAssociationAcceptor(true);
ae.addConnection(conn);
}
public void setPort(int nPort) {
if(conn == null) {
return;
}
conn.setPort(nPort);
}
public void setIP(String strIP) {
if(conn == null) {
return;
}
conn.setHostname(strIP);
}
public void setAETitle(String strAETitle) throws IOException {
ae.setAETitle(strAETitle);
ae.addTransferCapability(new TransferCapability(null, "*", TransferCapability.Role.SCP, "*"));
}
public void statrService() throws IOException, GeneralSecurityException {
device.setExecutor(executorService);
device.bindConnections();
}
private DicomServiceRegistry createServiceRegistry() {
DicomServiceRegistry serviceRegistry = new DicomServiceRegistry();
serviceRegistry.addDicomService(new BasicCEchoSCP());
serviceRegistry.addDicomService(cstoreSCP);
return serviceRegistry;
}
private void storeTo(Association as, Attributes fmi,
PDVInputStream data, File file) throws IOException {
file.getParentFile().mkdirs();
DicomOutputStream out = new DicomOutputStream(file);
try {
out.writeFileMetaInformation(fmi);
data.copyTo(out);
} finally {
SafeClose.close(out);
}
}
private void renameTo(Association as, File from, File dest)
throws IOException {
if (!dest.getParentFile().mkdirs())
dest.delete();
if (!from.renameTo(dest))
throw new IOException("Failed to rename " + from + " to " + dest);
}
}
MAIN方法
public static void main(String[] args) {
Dcm2cheStoreSCP scp = new Dcm2cheStoreSCP();
scp.setIP("127.0.0.1");
scp.setPort(11112);
try {
scp.setAETitle("AIRKING");
scp.statrService();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
测试
打开cmd进入(你的目录)\dcm4che-5.21.0\bin目录下,运行下面的命令
查看目录(D:/dicomFile/cacheData/):
到此为止storescp的实现已经完成