How to Import PDF to DICOMPDF
Import general PDF files and turn them into DICOM PDF format is not much different to import other file formats, i.e. windows Bitmap and Jpeg images.
Based on the DICOM supplement 104, we made two small programs (VB6 using COM version and CSharp using .NET version) which demonstrate what attributes are needed for making a valid DICOM PDF file.
DicomObjects.NET
DicomDataSet pdf = new DicomDataSet();
// Read in PDF file as Byte array
byte[] data = File.ReadAllBytes(file);
// ==== Patient Module Attributes ====
pdf.Add(0x10, 0x10, "Patient Name 123"); // Patient Name
pdf.Add(0x10, 0x20, 123456); // Patient ID
pdf.Add(0x10, 0x30, ""); // Patient DOB
pdf.Add(0x10, 0x40, "O"); // Patient Sex
// ==== Study Module Attributes ====
pdf.Add(0x20, 0xD, DicomGlobal.NewUID()); // Study Instance UID
pdf.Add(0x8, 0x20, ""); // Study Date
pdf.Add(0x8, 0x30, ""); // Study Time
pdf.Add(0x8, 0x90, ""); // Referring Physician//s Name
pdf.Add(0x20, 0x10, 1); // Study ID
pdf.Add(0x8, 0x50, ""); // Accession Number
// ==== Encapsulated Document Series Module Attributes ====
pdf.Add(0x8, 0x60, "OT"); // Modality
pdf.Add(0x20, 0xE, DicomGlobal.NewUID()); // Series Instance UID
pdf.Add(0x20, 0x11, 1); // Series Number
// ==== General Equipment Module Attributes ====
pdf.Add(0x8, 0x70, ""); // Manufacturer
// ==== SC EQUIPMENT MODULE ATTRIBUTES ====
pdf.Add(0x8, 0x64, "SD"); // Conversion Type
// ==== Encapsulated Document Module Attributes ====
pdf.Add(0x20, 0x13, 1); // Instance Number
pdf.Add(0x8, 0x23, ""); // Content Date
pdf.Add(0x8, 0x33, ""); // Content Time
pdf.Add(0x8, 0x2A, ""); // Acquisition Datetime
pdf.Add(0x28, 0x301, "NO"); // Burned In Annotation
pdf.Add(0x42, 0x10, ""); // Document Title
pdf.Add(0x40, 0xA043, ""); // Concept Name Code Sequence, a coded representation of the document title
pdf.Add(0x42, 0x12, "application/pdf"); // MIME Type pf Encapsulated Document
pdf.Add(0x42, 0x11, data); // Encapsulated Document stream
// containing a document encoded according to the MIME Type
// ==== SOP Common ====
pdf.Add(0x8, 0x16, "1.2.840.10008.5.1.4.1.1.104.1"); // SOP Class UID
pdf.Add(0x8, 0x18, DicomGlobal.NewUID()); // SOP Instance UID
pdf.Write("c:DICOM_PDF.dcm", "1.2.840.10008.1.2.1");
DicomObjects.COM
Dim g As New DicomGlobal
Dim pdf As New DicomDataSet
Dim pdfData() As Byte
Dimfile_length As Long
Dimfnum As Integer
' Read in PDF file as Byte array
CommonDialog1.Filter = "*.pdf|*.pdf"
CommonDialog1.ShowOpen
If CommonDialog1.FileName <> "" Then
file_length = FileLen(CommonDialog1.FileName)
fnum = FreeFile
ReDim pdfData(1 To file_length)
Open CommonDialog1.FileName For Binary As #fnum
Get #fnum, 1, pdfData
Close fnum
Else
MsgBox "No file specified."
Exit Sub
End If
' ==== Patient Module Attributes ====
pdf.Attributes.Add &H10, &H10, "Patient Name 123" ' Patient Name
pdf.Attributes.Add &H10, &H20, 123456 ' Patient ID
pdf.Attributes.Add &H10, &H30, "" ' Patient DOB
pdf.Attributes.Add &H10, &H40, "O" ' Patient Sex
' ==== Study Module Attributes ====
pdf.Attributes.Add &H20, &HD, g.NewUID ' Study Instance UID
pdf.Attributes.Add &H8, &H20, "" ' Study Date
pdf.Attributes.Add &H8, &H30, "" ' Study Time
pdf.Attributes.Add &H8, &H90, "" ' Referring Physician's Name
pdf.Attributes.Add &H20, &H10, 1 ' Study ID
pdf.Attributes.Add &H8, &H50, "" ' Accession Number
' ==== Encapsulated Document Series Module Attributes ====
pdf.Attributes.Add &H8, &H60, "OT" ' Modality
pdf.Attributes.Add &H20, &HE, g.NewUID ' Series Instance UID
pdf.Attributes.Add &H20, &H11, 1 ' Series Number
' ==== General Equipment Module Attributes ====
pdf.Attributes.Add &H8, &H70, "" ' Manufacturer
' ==== SC EQUIPMENT MODULE ATTRIBUTES ====
pdf.Attributes.Add &H8, &H64, "SD" ' Conversion Type
' ==== Encapsulated Document Module Attributes ====
pdf.Attributes.Add &H20, &H13, 1 ' Instance Number
pdf.Attributes.Add &H8, &H23, "" ' Content Date
pdf.Attributes.Add &H8, &H33, "" ' Content Time
pdf.Attributes.Add &H8, &H2A, "" ' Acquisition Datetime
pdf.Attributes.Add &H28, &H301, "NO" ' Burned In Annotation
pdf.Attributes.Add &H42, &H10, "" ' Document Title
pdf.Attributes.Add &H40, &HA043, "" ' Concept Name Code Sequence, a coded representation of the document title
pdf.Attributes.Add &H42, &H12, "application/pdf" ' MIME Type pf Encapsulated Document
pdf.Attributes.Add &H42, &H11, pdfData ' Encapsulated Document stream, containing a document encoded
according to the MIME Type
' ==== SOP Common ====
pdf.Attributes.Add &H8, &H16, "1.2.840.10008.5.1.4.1.1.104.1" ' SOP Class UID
pdf.Attributes.Add &H8, &H18, g.NewUID ' SOP Instance UID
'' Write file out
pdf.WriteFile "c:DICOM_PDF.dcm", True, "1.2.840.10008.1.2.1"
Notes
.NET Setup
Appropriate .NET pdf dlls are required to load DICOM encapsulated PDF. They need to be referenced or simply copied over to the output directory (next to DicomObjects dll’s).
Our download package includes both 32 and 64 bit versions of the PDF dll to suit your program’s “bitness”.
CLR 4.0 package includes ceTe.DynamicPDF.Viewer.40.x86 & ceTe.DynamicPDF.Viewer.40.x64
CLR 3.5 package includes ceTe.DynamicPDF.Viewer.35.x86 & ceTe.DynamicPDF.Viewer.35.x64
x86 and x64 in the filename specifies what bit a dll is compiled against. Once the DLL’s are in the correct folders, DicomObjects will dynamically load them IF they are needed in your project.
For user defined location of those PDF dll’s, “PDFLibraryLocation” regstring can be set. You can set this by doing the following:
DicomGlobal.SetRegString("**PDFLibraryLocation**", "<Path to PDFDLL>");
COM Setup
COM uses the 32 bit version of the .NET PDF dll included in the package and it requires the NetWrapper object to bridge between the COM code and the .NET PDF dll.
CLR 3.5 package includes ceTe.DynamicPDF.Viewer.35.x86 & NetWrappers
Once the DLL’s are in the correct folders, DicomObjects will dynamically load them IF they are needed in your project.