dcm4che中使用getscu需要PACS配置你的AE相关信息(ip,aet和port)。
-
项目resources/lib下引入相关jar包(dcm4che-5.31.0相关jar)。
-
引入配置文件
相关代码如下:
修改188行 “你的AEtitle”
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.crzn.jcyyTrans.domain.VParseDcmNormal;
import com.crzn.jcyyTrans.service.impl.DcmTaskServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.ElementDictionary;
import org.dcm4che3.data.Tag;
import org.dcm4che3.data.VR;
import org.dcm4che3.io.DicomInputStream;
import org.dcm4che3.net.*;
import org.dcm4che3.net.pdu.AAssociateRQ;
import org.dcm4che3.net.pdu.ExtendedNegotiation;
import org.dcm4che3.net.pdu.PresentationContext;
import org.dcm4che3.net.pdu.RoleSelection;
import org.dcm4che3.net.service.BasicCStoreSCP;
import org.dcm4che3.net.service.DicomServiceRegistry;
import org.dcm4che3.tool.common.CLIUtils;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@Slf4j
@Component
public class GetSCU {
public static enum InformationModel {
PatientRoot("1.2.840.10008.5.1.4.1.2.1.3", "STUDY"), StudyRoot("1.2.840.10008.5.1.4.1.2.2.3", "STUDY"), PatientStudyOnly("1.2.840.10008.5.1.4.1.2.3.3", "STUDY"), CompositeInstanceRoot("1.2.840.10008.5.1.4.1.2.4.3", "IMAGE"), WithoutBulkData("1.2.840.10008.5.1.4.1.2.5.3", null), HangingProtocol("1.2.840.10008.5.1.4.38.4", null), ColorPalette("1.2.840.10008.5.1.4.39.4", null);
final String cuid;
final String level;
InformationModel(String cuid, String level) {
this.cuid = cuid;
this.level = level;
}
public void adjustQueryOptions(EnumSet<QueryOption> queryOptions) {
if (level == null) {
queryOptions.add(QueryOption.RELATIONAL);
queryOptions.add(QueryOption.DATETIME);
}
}
}
private static ResourceBundle rb = ResourceBundle.getBundle("message", Locale.getDefault());
;
private static final int[] DEF_IN_FILTER = {Tag.SOPInstanceUID, Tag.StudyInstanceUID, Tag.SeriesInstanceUID};
private final Device device = new Device("get-scu");
private final ApplicationEntity ae;
private final Connection conn = new Connection();
private final Connection remote = new Connection();
private final AAssociateRQ rq = new AAssociateRQ();
private int priority;
private InformationModel model;
private Attributes keys = new Attributes();
private int[] inFilter = DEF_IN_FILTER;
private Association as;
private int cancelAfter;
private static String[] IVR_LE_FIRST = new String[]{"1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.2"};
private static final String DCM_EXT = ".dcm";
/**
* 接收到dicom文件的存储目录
*/
private String storageDir = rb.getString("storageDir");
private BasicCStoreSCP storageSCP = new BasicCStoreSCP("*") {
@Override
protected void store(Association as, PresentationContext pc, Attributes rq, PDVInputStream data, Attributes rsp) {
try {
// 获取DICOM文件信息
String sopInstanceUID = rq.getString(Tag.AffectedSOPInstanceUID);
//读取dcm文件方法
File tempFile = FileUtil.createTempFile("tempDcm_", ".dcm", true);
// 创建文件输出流
FileOutputStream fos = null;
try {
fos = new FileOutputStream(tempFile, true);
// 将DICOM数据写入文件
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = data.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//关闭文件流
fos.flush();
fos.close();
}
if (!tempFile.exists()) {
log.info("文件不存在,跳出循环继续下一次, 路径为:{}", tempFile.getPath());
return;
}
DicomInputStream dis = new DicomInputStream(tempFile);
dis.setIncludeBulkData(DicomInputStream.IncludeBulkData.URI);
Attributes attr = dis.readDataset(-1, -1);
//关闭流
dis.close();
//保存dcm字段信息
VParseDcmNormal parseDcmNormal = new VParseDcmNormal();
/*
* Patient Tag
*/
parseDcmNormal.setPatientName(attr.getString(Tag.PatientName));
parseDcmNormal.setPatientID(attr.getString(Tag.PatientID));
parseDcmNormal.setPatientSex(attr.getString(Tag.PatientSex));
/*
* Study Tag
*/
parseDcmNormal.setAccessionNumber(String.valueOf(Tag.AccessionNumber));
parseDcmNormal.setStudyID(attr.getString(Tag.StudyID));
parseDcmNormal.setStudyInstanceUID(attr.getString(Tag.StudyInstanceUID));
parseDcmNormal.setStudyDate(attr.getString(Tag.StudyDate));
parseDcmNormal.setStudyTime(attr.getString(Tag.StudyTime));
parseDcmNormal.setModalitiesInStudy(attr.getString(Tag.ModalitiesInStudy));
parseDcmNormal.setStudyDescription(attr.getString(Tag.StudyDescription));
parseDcmNormal.setPatientAge(attr.getString(Tag.PatientAge));
/*
* Series Tag
*/
parseDcmNormal.setSeriesNumber(attr.getInt(Tag.SeriesNumber, 0));
parseDcmNormal.setSeriesInstanceUID(attr.getString(Tag.SeriesInstanceUID));
//检查模态(MRI/CT/CR/DR)
parseDcmNormal.setModality(attr.getString(Tag.Modality));
parseDcmNormal.setSeriesDescription(attr.getString(Tag.SeriesDescription));
parseDcmNormal.setSeriesDate(attr.getString(Tag.SeriesDate));
parseDcmNormal.setSeriesTime(attr.getString(Tag.SeriesTime));
//图像位置:图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米.如果在检查中,则指该序列中第一张影像左上角的坐标.
parseDcmNormal.setImagePositionPatient(attr.getString(Tag.ImagePositionPatient));
//层厚
parseDcmNormal.setSliceThickness(attr.getString(Tag.SliceThickness));
//身体部位.
parseDcmNormal.setBodyPartExamined(attr.getString(Tag.BodyPartExamined));
/*
* Image Tag
*/
String imageTypes = attr.getString(Tag.ImageType);
String[] imageType = imageTypes.split("\\\\");
parseDcmNormal.setImageType(Arrays.asList(imageType).toString());
parseDcmNormal.setSOPInstanceUID(attr.getString(Tag.SOPInstanceUID));
parseDcmNormal.setContentDate(attr.getString(Tag.ContentDate));
parseDcmNormal.setContentTime(attr.getString(Tag.ContentTime));
parseDcmNormal.setInstanceNumber(attr.getInt(Tag.InstanceNumber, 0));
parseDcmNormal.setWindowCenter(attr.getString(Tag.WindowCenter));
parseDcmNormal.setWindowWidth(attr.getString(Tag.WindowWidth));
parseDcmNormal.setCreateDate(DateUtil.now());
//删除临时文件
tempFile.delete();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
public GetSCU() throws IOException {
ae = new ApplicationEntity("你的AE title");
device.addConnection(conn);
device.addApplicationEntity(ae);
ae.addConnection(conn);
device.setDimseRQHandler(createServiceRegistry());
}
public ApplicationEntity getApplicationEntity() {
return ae;
}
public Connection getRemoteConnection() {
return remote;
}
public AAssociateRQ getAAssociateRQ() {
return rq;
}
public Association getAssociation() {
return as;
}
public Device getDevice() {
return device;
}
public Attributes getKeys() {
return keys;
}
private DicomServiceRegistry createServiceRegistry() {
DicomServiceRegistry serviceRegistry = new DicomServiceRegistry();
serviceRegistry.addDicomService(storageSCP);
return serviceRegistry;
}
public final void setPriority(int priority) {
this.priority = priority;
}
private static void configureStorageSOPClass(GetSCU main, String cuid, String tsuids0) {
String[] tsuids1 = StringUtils.split(tsuids0, ';');
for (String tsuids2 : tsuids1) {
main.addOfferedStorageSOPClass(CLIUtils.toUID(cuid), CLIUtils.toUIDs(tsuids2));
}
}
public void addOfferedStorageSOPClass(String cuid, String... tsuids) {
if (!rq.containsPresentationContextFor(cuid)) {
rq.addRoleSelection(new RoleSelection(cuid, false, true));
}
rq.addPresentationContext(new PresentationContext(2 * rq.getNumberOfPresentationContexts() + 1, cuid, tsuids));
}
private void setInformationModel(InformationModel model, String[] tss, EnumSet<QueryOption> queryOptions) {
this.model = model;
rq.addPresentationContext(new PresentationContext(1, model.cuid, tss));
if (!queryOptions.isEmpty()) {
model.adjustQueryOptions(queryOptions);
rq.addExtendedNegotiation(new ExtendedNegotiation(model.cuid, QueryOption.toExtendedNegotiationInformation(queryOptions)));
}
if (model.level != null) {
addLevel(model.level);
}
}
public void addLevel(String s) {
keys.setString(Tag.QueryRetrieveLevel, VR.CS, s);
}
public void addKey(int tag, String... ss) {
VR vr = ElementDictionary.vrOf(tag, keys.getPrivateCreator(tag));
keys.setString(tag, vr, ss);
}
private static void addRetrieveLevelOption(Options opts) {
opts.addOption(Option.builder("L").hasArg().argName("PATIENT|STUDY|SERIES|IMAGE|FRAME").desc(rb.getString("level")).build());
}
/**
* 配置远程连接
*
* @param conn Connection
* @param rq AAssociateRQ
*/
private void configureConnect(Connection conn, AAssociateRQ rq) throws ParseException {
// 获取title属性值
String title = rb.getString("title");
if (org.apache.commons.lang3.StringUtils.isBlank(title)) {
throw new ParseException("title cannot be missing");
}
// 设置AE title
rq.setCalledAET(title);
// 读取host和port属性值
String host = rb.getString("host");
String port = rb.getString("port");
if (org.apache.commons.lang3.StringUtils.isBlank(host) || org.apache.commons.lang3.StringUtils.isBlank(port)) {
throw new ParseException("host or port cannot be missing");
}
// 设置host和por
conn.setHostname(host);
conn.setPort(Integer.parseInt(port));
}
private void configureKeys(Attributes keys) {
this.keys.addAll(keys);
}
private static EnumSet<QueryOption> queryOptionsOf() {
return EnumSet.noneOf(QueryOption.class);
}
/**
* 设置Information Model
*
* @param main
* @throws ParseException
*/
private static void configureServiceClass(GetSCU main) throws ParseException, IOException {
main.setInformationModel(informationModelOf(), IVR_LE_FIRST, queryOptionsOf());
String[] files = new String[]{"resource:store-tcs.properties"};
if (files != null) {
for (String file : files) {
Properties p = CLIUtils.loadProperties(file, null);
Set<Map.Entry<Object, Object>> entrySet = p.entrySet();
for (Map.Entry<Object, Object> entry : entrySet) {
configureStorageSOPClass(main, (String) entry.getKey(), (String) entry.getValue());
}
}
}
}
private static InformationModel informationModelOf() throws ParseException {
try {
String model = rb.getString("model");
// 如果model为空,默认StudyRoot
return StringUtils.isNotBlank(model) ? InformationModel.valueOf(model) : InformationModel.StudyRoot;
} catch (IllegalArgumentException e) {
throw new ParseException(MessageFormat.format(rb.getString("invalid-model-name"), rb.getString("model")));
}
}
private static void configureRetrieve(GetSCU main) {
if (StringUtils.isNotBlank(rb.getString("level"))) {
// Retrieve是指SCU通过Query 拿到信息后,要求对方根据请求级别 (Patient/Study/Series/Image) 发送影像给己方。
// 默认Patient
main.addLevel(rb.getString("level"));
}
}
private static int priorityOf() {
String high = rb.getString("prior-high");
String low = rb.getString("prior-low");
return StringUtils.isNotBlank(high) ? 1 : (StringUtils.isNotBlank(low) ? 2 : 0);
}
public void matchingKeys(Attributes attrs) {
try {
GetSCU main = new GetSCU();
configureConnect(main.remote, main.rq); // 设置连接ip和端口 (远程)
main.remote.setTlsProtocols(main.conn.getTlsProtocols()); // 设置Tls协议
main.remote.setTlsCipherSuites(main.conn.getTlsCipherSuites());
configureServiceClass(main); // 设置Information Model
configureRetrieve(main); // 设置检索级别
//configureCancel(main); // 配置 --cancel
main.setPriority(priorityOf()); // 设置优先级
ExecutorService executorService = Executors.newSingleThreadExecutor(); // 单线程化线程池
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); // 定时任务
main.device.setExecutor(executorService);
main.device.setScheduledExecutor(scheduledExecutorService);
try {
main.open(); // 打开链接
main.configureKeys(attrs);
main.retrieve(); // 查询
} finally {
main.close();
executorService.shutdown();
scheduledExecutorService.shutdown();
while (true) {
if (scheduledExecutorService.isTerminated()) { // 计算耗时
break;
}
}
}
} catch (ParseException | InterruptedException | IncompatibleConnectionException | GeneralSecurityException |
IOException e) {
e.printStackTrace();
}
}
public void close() throws IOException, InterruptedException {
if (as != null && as.isReadyForDataTransfer()) {
as.waitForOutstandingRSP();
as.release();
}
}
private void open() throws IOException, InterruptedException, IncompatibleConnectionException, GeneralSecurityException {
as = ae.connect(conn, remote, rq);
}
public void retrieve() throws IOException, InterruptedException {
retrieve(keys);
}
private void retrieve(Attributes keys) throws IOException, InterruptedException {
DimseRSPHandler rspHandler = new DimseRSPHandler(as.nextMessageID()) {
@Override
public void onDimseRSP(Association as, Attributes cmd, Attributes data) {
super.onDimseRSP(as, cmd, data);
}
};
retrieve(keys, rspHandler);
}
private void retrieve(Attributes keys, DimseRSPHandler rspHandler) throws IOException, InterruptedException {
as.cget(model.cuid, priority, keys, null, rspHandler);
}
}
配置文件resources/ message.properties
修改配置文件前三行
title=pacs的AEtitle
host=pacs的ip
port=pacs端口
#specifies Information Model. Supported names: PatientRoot, StudyRoot, PatientStudyOnly,
#MWL, UPSPull, UPSWatch, UPSQuery, HangingProtocol or ColorPalette. If no Information Model is specified,
#StudyRoot will be used.
model=
invalid-model-name={0} is not a supported Information Model name
#specifies retrieve level. Use STUDY for PatientRoot, StudyRoot, PatientStudyOnly by default.
level=STUDY
#cancel the query request after the receive of the specified number of matches.
cancel=10
xml=write received mstorageDiratches as XML Infoset specified in DICOM Part 19
xsl=apply specified XSLT stylesheet to XML representation of received matches; implies -X
prior-high=
prior-low=
storageDir=/tempFiles/down
配置文件resources/ store-tcs.properties
不需要改任何内容
# Storage Transfer Capabilities for most common SOP Classes and Transfer Syntaxes
#
# Format: <sop-class>:<transfer-syntax>[(,|;)...]
#
# SOP Class and Transfer Syntaxes can be specified by its UID or its name in camel-Case.
# Semicolon separated Transfer Syntaxes will be offered in separate Presentation Contexts,
# where comma separated Transfer Syntaxes will be offered in one Presentation Context.
ComputedRadiographyImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
DigitalXRayImageStorageForPresentation:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
DigitalXRayImageStorageForProcessing:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
DigitalMammographyXRayImageStorageForPresentation:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
DigitalMammographyXRayImageStorageForProcessing:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#DigitalIntraOralXRayImageStorageForPresentation:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#DigitalIntraOralXRayImageStorageForProcessing:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
CTImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EnhancedCTImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#LegacyConvertedEnhancedCTImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
UltrasoundMultiFrameImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
MRImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EnhancedMRImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MRSpectroscopyStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EnhancedMRColorImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#LegacyConvertedEnhancedMRImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
UltrasoundImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EnhancedUSVolumeStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
SecondaryCaptureImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MultiFrameSingleBitSecondaryCaptureImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MultiFrameGrayscaleByteSecondaryCaptureImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MultiFrameGrayscaleWordSecondaryCaptureImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MultiFrameTrueColorSecondaryCaptureImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#TwelveLeadECGWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#GeneralECGWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#AmbulatoryECGWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#HemodynamicWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#CardiacElectrophysiologyWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#BasicVoiceAudioWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#GeneralAudioWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ArterialPulseWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RespiratoryWaveformStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
GrayscaleSoftcopyPresentationStateStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ColorSoftcopyPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#PseudoColorSoftcopyPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#BlendingSoftcopyPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#XAXRFGrayscaleSoftcopyPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#GrayscalePlanarMPRVolumetricPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#CompositingPlanarMPRVolumetricPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#AdvancedBlendingPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#VolumeRenderingVolumetricPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SegmentedVolumeRenderingVolumetricPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MultipleVolumeRenderingVolumetricPresentationStateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
XRayAngiographicImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EnhancedXAImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
XRayRadiofluoroscopicImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EnhancedXRFImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#XRay3DAngiographicImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#XRay3DCraniofacialImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#BreastTomosynthesisImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#BreastProjectionXRayImageStorageForPresentation:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#BreastProjectionXRayImageStorageForProcessing:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#IntravascularOpticalCoherenceTomographyImageStorageForPresentation:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#IntravascularOpticalCoherenceTomographyImageStorageForProcessing:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
NuclearMedicineImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ParametricMapStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RawDataStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SpatialRegistrationStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SpatialFiducialsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#DeformableSpatialRegistrationStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SegmentationStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SurfaceSegmentationStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#TractographyResultsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RealWorldValueMappingStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SurfaceScanMeshStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SurfaceScanPointCloudStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#VLEndoscopicImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#VideoEndoscopicImageStorage:\
#JPEGBaseline8Bit;MPEG2MPML
#VLMicroscopicImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#VideoMicroscopicImageStorage:\
#JPEGBaseline8Bit;MPEG2MPML
#VLSlideCoordinatesMicroscopicImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#VLPhotographicImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian;JPEGBaseline8Bit
#VideoPhotographicImageStorage:\
#JPEGBaseline8Bit;MPEG2MPML
#OphthalmicPhotography8BitImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#OphthalmicPhotography16BitImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#StereometricRelationshipStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#OphthalmicTomographyImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#WideFieldOphthalmicPhotographyStereographicProjectionImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#WideFieldOphthalmicPhotography3DCoordinatesImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#OphthalmicOpticalCoherenceTomographyEnFaceImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#OphthalmicOpticalCoherenceTomographyBscanVolumeAnalysisStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#VLWholeSlideMicroscopyImageStorage:\
#JPEGBaseline8Bit;JPEG2000Lossless;JPEG2000
#LensometryMeasurementsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#AutorefractionMeasurementsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#KeratometryMeasurementsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SubjectiveRefractionMeasurementsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#VisualAcuityMeasurementsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SpectaclePrescriptionReportStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#OphthalmicAxialMeasurementsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#IntraocularLensCalculationsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MacularGridThicknessAndVolumeReportStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#OphthalmicVisualFieldStaticPerimetryMeasurementsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#OphthalmicThicknessMapStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#CornealTopographyMapStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
BasicTextSRStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
EnhancedSRStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ComprehensiveSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#Comprehensive3DSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ExtensibleSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ProcedureLogStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#MammographyCADSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
KeyObjectSelectionDocumentStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ChestCADSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
XRayRadiationDoseSRStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ColonCADSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ImplantationPlanSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#AcquisitionContextSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#SimplifiedAdultEchoSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#PatientRadiationDoseSRStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ContentAssessmentResultsStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
EncapsulatedPDFStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EncapsulatedCDAStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EncapsulatedSTLStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
PositronEmissionTomographyImageStorage:\
ImplicitVRLittleEndian;ExplicitVRLittleEndian
#LegacyConvertedEnhancedPETImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#EnhancedPETImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#BasicStructuredDisplayStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#CTDefinedProcedureProtocolStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#CTPerformedProcedureProtocolStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ProtocolApprovalStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTImageStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTDoseStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTStructureSetStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTBeamsTreatmentRecordStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTPlanStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTBrachyTreatmentRecordStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTTreatmentSummaryRecordStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTIonPlanStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTIonBeamsTreatmentRecordStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTBeamsDeliveryInstructionStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#RTBrachyApplicationSetupDeliveryInstructionStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#HangingProtocolStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ColorPaletteStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#HangingProtocolStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#GenericImplantTemplateStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
#ImplantTemplateGroupStorage:\
#ImplicitVRLittleEndian;ExplicitVRLittleEndian
调用
public static void main(String[] args) {
Attributes attrs = new Attributes();
// 输入下载条件
attrs.setString(Tag.StudyInstanceUID, VR.UI, "1.2.826.0.1.3680043.2.461.13689436.3738165271");
//下载文件到本地
try {
new GetSCU().matchingKeys(attrs);
} catch (Exception e) {
throw new RuntimeException(e);
}
}