Build with confidence

  • Full source code1 (c++ and Objective-C included, Python & Java auto-generated by SWIG, Swift auto-generated by XCode bridge headers)
  • Extensive documentation
  • One year of support & upgrades
  • SDK requirements and risk analysis
  • Standard Operating Procedures used for the development of the SDK
  • Test units with test coverage report
  • Binary compatibility between minor releases

Send and receive DICOM messages

Communicate via DICOM messages (DIMSE) over network associations (ACSE).

DICOMHERO SDK can act as SCU, SCP or both and recognizes all the composite and normalized DIMSE commands.

AssociationSCU scu("SCU", scpName, 1, 1, presentationContexts, readSCU, writeSCU, 0);<br><br>DimseService dimse(scu);<br><br>CEchoCommand echoCommand(<br>    "1.2.840.10008.1.1",<br>    dimse.getNextCommandID(),<br>    dimseCommandPriority_t::medium,<br>    "1.1.1.1.1");<br><br>dimse.sendCommandOrResponse(echoCommand);<br><br>CEchoResponse response =<br>    dimse.getCEchoResponse(echoCommand);

DICOM & DICOMDIR files

Read and write DICOM and Jpeg files and have both high-level and raw access to the data.

Lazy loading allows the processing of large DICOM files.

DicomDir newDicomDir;<br><br>DicomDirEntry rootRecord = <br>    newDicomDir.getNewEntry("PATIENT");<br><br>DataSet dataSet(rootRecord.getEntryDataSet());<br>    dataSet.setUnicodeString(TagId(tagId_t::PatientName_0010_0010), L"Surname");<br>newDicomDir.setFirstRootEntry(rootRecord);

Supports compressed (lossy/lossless) and raw images

Decompress the embedded images or convert them to other color formats or bit depth. Supports raw, rle, jpeg baseline and jpeg lossless.

Transform transformToYBR = <br>    colorTransformsFactory::getTransform(<br>      "RGB", <br>      "YBR_FULL");<br>Image ybrImage = <br>    transformToYBR.allocateOutputImage(<br>      baselineImage, <br>      width, <br>      height);<br>transformToYBR.runTransform(<br>    baselineImage, <br>    0, 0, <br>    width, height, <br>    ybrImage, <br>    0, 0);

DICOMHERO Objects: the whole standard at your fingertips

DICOMHERO Objects brings the DICOM Standard CIODs, NIODs, modules & macros in C++ form.

Check how the DICOMHERO Objects library is used in the worklist example to query a modality worklist server.

// Create the C-FIND payload using the negotiated transfer syntax<br>DataSet dataSet(negotiatedTransferSyntaxes.front());<br>modules::PatientIdentification patient(dataSet);<br>patient.setPatientNameValue(dicomhero::PatientName("*", "",""));<br>patient.setPatientIDValue(patientID);<br>modules::ScheduledProcedureStep procedureStep(dataSet);<br>auto procedureSequenceItem = procedureStep.addScheduledProcedureStepSequenceItem();<br>// Create empty tags to signal that we want to receive the value back from the server<br>procedureSequenceItem.getScheduledStationAETitleTagCreate();<br>procedureSequenceItem.getScheduledProcedureStepStartDateTagCreate();<br>procedureSequenceItem.getScheduledProcedureStepIDTagCreate();<br>procedureSequenceItem.getModalityTagCreate();<br>procedureSequenceItem.getScheduledPerformingPhysicianNameTagCreate();<br>procedureSequenceItem.getScheduledProcedureStepDescriptionTagCreate();<br><br>// Build the C-FIND command using the payload we just created<br>CFindCommand cfind(<br>    dicom2018e::uidModalityWorklistInformationModelFIND,<br>    1,<br>    dimseCommandPriority_t::medium,<br>    dicom2018e::uidModalityWorklistInformationModelFIND,<br>    dataSet);<br><br>// Send the C-FIND command<br>dimse.sendCommandOrResponse(cfind);

Works with Python

Install DICOMHERO with pip3, build or parse DICOM Datasets with raw, RLE or Jpeg compressed images, communicate with other DICOM modalities via ACSE & DIMSE.

from dicomhero6 import dicomhero6<br><br>dataset = dicomhero6.DataSet()<br><br># Create an RGB image (16 bit per channel)<br>image = dicomhero6.Image(300, 100, dicomhero6.bitDepth_t_depthU16, "RGB", 15)<br><br># Generate test gradients<br>handler = image.getWritingDataHandler()<br>write_int_array = array.array('H', [0] * handler.getSize())<br>for y in range(0, 100):<br>    for x in range(0, 300):<br><br>        write_int_array[(y * 300 + x) * 3] = y<br>        write_int_array[(y * 300 + x) * 3 + 1] = x<br>        write_int_array[(y * 300 + x) * 3 + 2] = x + 1<br><br>memory = handler.getMemory()<br>memory.assign(write_int_array)<br>handler = None # Force the handler to write into the image<br><br>dataset.setImage(0, image, dicomhero6.imageQuality_t_high)<br>dicomhero6.CodecFactory.save(dataset, "test.dcm", dicomhero6.codecType_t_dicom)

Works with Java

DICOMHERO can be compiled into an aar library using AndroidStudio and the NDK.

Using the DICOMHERO Bitmap class you can generate pixel buffers ready to be displayed on Android devices.

// The CodecFactory will read from the Pipe which is feed by the thread launched<br>// before. We could just pass a file name to it but this would limit what we<br>// can read to only local files<br>DataSet loadDataSet = CodecFactory.load(new StreamReader(dicomheroPipe.getStreamInput()));<br><br><br>// Get the first frame from the dataset (after the proper modality transforms<br>// have been applied).<br>Image dicomImage = loadDataSet.getImageApplyModalityTransform(0);<br><br>// Use a DrawBitmap to build a stream of bytes that can be handled by the<br>// Android Bitmap class.<br>TransformsChain chain = new TransformsChain();<br><br>if(ColorTransformsFactory.isMonochrome(dicomImage.getColorSpace()))<br>{<br>    VOILUT voilut = new VOILUT(VOILUT.getOptimalVOI(dicomImage, 0, 0, dicomImage.getWidth(), dicomImage.getHeight()));<br>    chain.addTransform(voilut);<br>}<br>DrawBitmap drawBitmap = new DrawBitmap(chain);<br>Memory memory = drawBitmap.getBitmap(dicomImage, drawBitmapType_t.drawBitmapRGBA, 4);<br><br>// Build the Android Bitmap from the raw bytes returned by DrawBitmap.<br>Bitmap renderBitmap = Bitmap.createBitmap((int)dicomImage.getWidth(), (int)dicomImage.getHeight(), Bitmap.Config.ARGB_8888);<br>byte[] memoryByte = new byte[(int)memory.size()];<br>memory.data(memoryByte);<br>ByteBuffer byteBuffer = ByteBuffer.wrap(memoryByte);<br>renderBitmap.copyPixelsFromBuffer(byteBuffer);<br><br>// Update the image<br>mImageView.setImageBitmap(renderBitmap);<br>mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);<br><br>// Update the text with the patient name<br>mTextView.setText(loadDataSet.getPatientName(new TagId(0x10,0x10), 0, new PersonName("Undefined", "", "")).getAlphabeticRepresentation());

Unicode support

DICOMHERO translates Unicode strings to/from multiple DICOM charsets.

structuredReport.addPatientModule()<br>    .setPatientNameUnicodeValue(<br>      UnicodePersonName(<br>        L"Test^Patient", <br>        L"", <br>        L""))<br>    .setPatientBirthDateValue(<br>      Date(<br>        2020, 1, 1, <br>        10, 0, 0, 0, 0, 0));

Source available

DICOMHERO comes with full source code.
Commercial royalty-free licenses and support are available.

Self-contained

DICOMHERO depends only on the default OS libraries.


Multi-platform

DICOMHERO runs on:

  • Linux
  • Windows
  • iOS
  • macOS
  • Android

Multi-language

Written in C++, wrappers for:

  • Python
  • Java
  • Objective-C
  • Swift

  1. The full source code is available to the commercial license holders ↩︎