Java中使用dcm4che操作dicom之GetScu(c-get)

dcm4che中使用getscu需要PACS配置你的AE相关信息(ip,aet和port)。

  1.  项目resources/lib下引入相关jar包(dcm4che-5.31.0相关jar)。

  2. 引入配置文件

相关代码如下:

修改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);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值