├── examples ├── dcm_temp │ ├── placeholder.txt │ └── store_server.log ├── pdf.pdf ├── dean.dcm ├── test.dcm ├── test.jpg ├── store_server.php ├── get_tags_webbased.php ├── write_tags.php ├── get_tags.php ├── dcm_to_jpg.php ├── send_dcm.php ├── compress.php ├── uncompress.php ├── store_server_handler.php ├── send_directory.php ├── jpg_to_dcm.php ├── jpg_to_dcm.xml └── store_server_config.cfg ├── README └── class_dicom.php /examples/dcm_temp/placeholder.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedicveko/class_dicom.php/HEAD/examples/pdf.pdf -------------------------------------------------------------------------------- /examples/dean.dcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedicveko/class_dicom.php/HEAD/examples/dean.dcm -------------------------------------------------------------------------------- /examples/test.dcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedicveko/class_dicom.php/HEAD/examples/test.dcm -------------------------------------------------------------------------------- /examples/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedicveko/class_dicom.php/HEAD/examples/test.jpg -------------------------------------------------------------------------------- /examples/dcm_temp/store_server.log: -------------------------------------------------------------------------------- 1 | 20110407 13:52:46 - Received DAVIS^ALEXANDER-DOCUM from Dean -> Dean 2 | 20110407 13:52:46 - Received DAVIS^ALEXANDER from Dean -> Dean 3 | 20110407 13:52:46 - Received DAVIS^ALEXANDER from Dean -> Dean 4 | 20110407 14:22:54 - Received VAUGHAN^DEAN from example -> DEANO 5 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | A PHP class that lets you work with DICOM tags, convert to jpg, compress, uncompress, receive, and send images. 2 | 3 | My aim was to keep the interface as simple as possible while at the same time providing a class that would be easy to grow. 4 | 5 | SEE: http://www.deanvaughan.org/projects/class_dicom_php/ 6 | 7 | -------------------------------------------------------------------------------- /examples/store_server.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | store_server(104, './dcm_temp', './store_server_handler.php', 'store_server_config.cfg', 1); 12 | 13 | ?> 14 | -------------------------------------------------------------------------------- /examples/get_tags_webbased.php: -------------------------------------------------------------------------------- 1 | file = $file; 16 | $d->load_tags(); 17 | 18 | print "
";
19 | 
20 | print_r($d->tags);
21 | 
22 | $name = $d->get_tag('0010', '0010');
23 | print "Name: $name\n";
24 | 
25 | ?>
26 | 


--------------------------------------------------------------------------------
/examples/write_tags.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | file = 'dean.dcm';
10 | 
11 | $new_tags = array(
12 |   '0010,0010' => 'VAUGHAN^DEAN',
13 |   '0008,0080' => 'DEANLAND, AR'
14 | );
15 | 
16 | 
17 | $result = $d->write_tags($new_tags);
18 | 
19 | if($result) {
20 |   print "$result\n";
21 | }
22 | else {
23 |   system("./get_tags.php " . $d->file);
24 | }
25 | 
26 | ?>
27 | 


--------------------------------------------------------------------------------
/examples/get_tags.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | \n";
13 |   exit;
14 | }
15 | 
16 | if(!file_exists($file)) {
17 |   print "$file: does not exist\n";
18 |   exit;
19 | }
20 | 
21 | $d = new dicom_tag($file);
22 | $d->load_tags();
23 | 
24 | print_r($d->tags);
25 | 
26 | $name = $d->get_tag('0010', '0010');
27 | print "Name: $name\n";
28 | 
29 | ?>
30 | 


--------------------------------------------------------------------------------
/examples/dcm_to_jpg.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | \n";
13 |   exit;
14 | }
15 | 
16 | if(!file_exists($file)) {
17 |   print "$file: does not exist\n";
18 |   exit;
19 | }
20 | 
21 | $job_start = time();
22 | 
23 | $d = new dicom_convert;
24 | $d->file = $file;
25 | $d->dcm_to_jpg();
26 | $d->dcm_to_tn();
27 | 
28 | system("ls -lsh $file*");
29 | 
30 | $job_end = time();
31 | $job_time = $job_end - $job_start;
32 | print "Created JPEG and thumbnail in $job_time seconds.\n";
33 | 
34 | 
35 | ?>
36 | 


--------------------------------------------------------------------------------
/examples/send_dcm.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | \n";
13 |   exit;
14 | }
15 | 
16 | if(!file_exists($file)) {
17 |   print "$file: does not exist\n";
18 |   exit;
19 | }
20 | 
21 | $d = new dicom_net;
22 | $d->file = $file;
23 | 
24 | print "Sending file...\n";
25 | 
26 | $out = $d->send_dcm('localhost', '104', 'DEANO', 'example');
27 | 
28 | if($out) {
29 |   print "$out\n\nSomething bad happened!\n";
30 |   exit;
31 | }
32 | 
33 | print "Sent!\n";
34 | 
35 | ?>
36 | 


--------------------------------------------------------------------------------
/examples/compress.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | \n";
13 |   exit;
14 | }
15 | 
16 | if(!file_exists($file)) {
17 |   print "$file: does not exist\n";
18 |   exit;
19 | }
20 | 
21 | $d = new dicom_tag;
22 | $d->file = $file;
23 | $d->load_tags();
24 | $ts = $d->get_tag('0002', '0010');
25 | $fsize = filesize($file);
26 | print "Original: $ts ($fsize)\n";
27 | 
28 | $c = new dicom_convert;
29 | $c->file = $file;
30 | $c->compress('compressed.dcm');
31 | 
32 | 
33 | $d->file = 'compressed.dcm';
34 | $d->load_tags();
35 | $ts = $d->get_tag('0002', '0010');
36 | $fsize = filesize($d->file);
37 | print "Compressed: $ts ($fsize)\n";
38 | 
39 | ?>
40 | 


--------------------------------------------------------------------------------
/examples/uncompress.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | \n";
13 |   exit;
14 | }
15 | 
16 | if(!file_exists($file)) {
17 |   print "$file: does not exist\n";
18 |   exit;
19 | }
20 | 
21 | $d = new dicom_tag;
22 | $d->file = $file;
23 | $d->load_tags();
24 | $ts = $d->get_tag('0002', '0010');
25 | $fsize = filesize($d->file);
26 | print "Original: $ts ($fsize)\n";
27 | 
28 | $c = new dicom_convert;
29 | $c->file = $file;
30 | $c->uncompress('uncompressed.dcm');
31 | 
32 | 
33 | $d->file = 'uncompressed.dcm';
34 | $d->load_tags();
35 | $ts = $d->get_tag('0002', '0010');
36 | $fsize = filesize($d->file);
37 | print "Uncompressed: $ts ($fsize)\n";
38 | 
39 | ?>
40 | 


--------------------------------------------------------------------------------
/examples/store_server_handler.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | file = "$dir/$file";
35 | 
36 | if(!file_exists($d->file)) {
37 |   logger($d->file . ": does not exist");
38 |   exit;
39 | }
40 | 
41 | 
42 | $d->load_tags();
43 | $name = $d->get_tag('0010', '0010');
44 | logger("Received $name from $sent_to_ae -> $sent_from_ae");
45 | 
46 | ?>
47 | 


--------------------------------------------------------------------------------
/examples/send_directory.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | file = "$temp_dir/$file";
28 |       $ret = $d->send_dcm($target_host, $target_port, $my_ae, $target_ae);
29 |       if($ret) {
30 |         print "Send Error: $ret\n";
31 |         continue;
32 |       }
33 |       else {
34 |         print "Good Send\n";
35 |         print "Moving $temp_dir/$file\n";
36 |         rename("$temp_dir/$file", "bk/$file");
37 |       }
38 | 
39 |     }
40 |   }
41 |   closedir($handle);
42 | }
43 | 
44 | ?>
45 | 


--------------------------------------------------------------------------------
/examples/jpg_to_dcm.php:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/php
 2 | jpg_file = 'test.jpg';
11 | $d->template = 'jpg_to_dcm.xml';
12 | $d->temp_dir = 'dcm_temp';
13 | 
14 | $tags = array(
15 |   '0008,0012' =>  date('Ymd'),
16 |   '0008,0013' =>  date('Gis'), 
17 |   '0008,0050' => 'ACCESSION123', 
18 |   '0008,0080' => 'General Hospital', 
19 |   '0008,0090' => 'Dr. Dean',
20 |   '0008,1030' => 'Study Description',
21 |   '0008,103e' => 'Series Description',
22 |   '0010,0010' => 'VAUGHAN^DEAN',
23 |   '0010,0020' => 'ID12345',
24 |   '0010,0030' => '19700303',
25 |   '0010,0040' => 'M',
26 |   '0010,21b0' => 'Patient History',
27 |   '0010,4000' => 'Patient Comments',
28 |   '0018,0015' => 'Head',
29 |   '0020,000d' => '1.3.51.0.7.2822962297.26312.19209.44846.7354.10266.42',
30 |   '0020,000e' => '1.3.51.5156.4083.' . date('Ymd') .'.42',
31 |   '0020,0011' => '1',
32 |   '0020,0012' => '1',
33 |   '0020,0013' => '1',
34 | );
35 | 
36 | $dcm = $d->jpg_to_dcm($tags);
37 | 
38 | print "New file is $dcm\n";
39 | 
40 | 
41 | ?>
42 | 


--------------------------------------------------------------------------------
/examples/jpg_to_dcm.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 180
 5 | 1.2.840.10008.5.1.4.1.1.1
 6 | 1.3.51.5156.4083.20080612.1175700.1
 7 | 1.2.840.10008.1.2.1
 8 | 1.2.276.0.7230010.3.0.3.5.4
 9 | DEANO
10 | 
11 | 
12 | DERIVED\PRIMARY
13 | (0008,0012)
14 | (0008,0013)
15 | 1.2.840.10008.5.1.4.1.1.1
16 | 1.3.51.5156.4083.(0008,0012).1175700.1
17 | (0008,0012)
18 | (0008,0012)
19 | (0008,0013)
20 | (0008,0013)
21 | (0008,0050)
22 | CR
23 | DEANO
24 | (0008,0080)
25 | (0008,0090)
26 | DEANO
27 | (0008,1030)
28 | (0008,103e)
29 | DEANO
30 | DEANO
31 | (0010,0010)
32 | (0010,0020)
33 | (0010,0030)
34 | (0010,0040)
35 | (0010,21b0)
36 | (0010,4000)
37 | (0018,0015)
38 | (0020,000d)
39 | (0020,000e)
40 | DEAN
41 | (0020,0011)
42 | (0020,0013)
43 | (0020,0012)
44 | 
45 | 
46 | 


--------------------------------------------------------------------------------
/examples/store_server_config.cfg:
--------------------------------------------------------------------------------
  1 | #
  2 | #  Copyright (C) 2003-2006, OFFIS
  3 | #
  4 | #  This software and supporting documentation were developed by
  5 | #
  6 | #    Kuratorium OFFIS e.V.
  7 | #    Healthcare Information and Communication Systems
  8 | #    Escherweg 2
  9 | #    D-26121 Oldenburg, Germany
 10 | #
 11 | #  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
 12 | #  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
 13 | #  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
 14 | #  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
 15 | #  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
 16 | #
 17 | #  Module:  dcmnet
 18 | #
 19 | #  Author:  Marco Eichelberg
 20 | #
 21 | #  Purpose: Sample configuration file for storescp
 22 | #
 23 | #  Last Update:      $Author: meichel $
 24 | #  Update Date:      $Date: 2006-06-15 15:30:50 $
 25 | #  CVS/RCS Revision: $Revision: 1.7 $
 26 | #  Status:           $State: Exp $
 27 | #
 28 | 
 29 | # ============================================================================
 30 | [[TransferSyntaxes]]
 31 | # ============================================================================
 32 | 
 33 | [AnyTransferSyntax]
 34 | TransferSyntax1  = JPEGExtended:Process2+4
 35 | TransferSyntax2  = JPEGBaseline
 36 | TransferSyntax3  = JPEGLossless:Non-hierarchical-1stOrderPrediction
 37 | TransferSyntax4  = JPEGLSLossy
 38 | TransferSyntax5  = JPEGLSLossless
 39 | TransferSyntax6  = RLELossless
 40 | TransferSyntax7  = MPEG2MainProfile@MainLevel
 41 | TransferSyntax8  = JPEG2000
 42 | TransferSyntax9  = JPEG2000LosslessOnly
 43 | TransferSyntax10 = DeflatedLittleEndianExplicit
 44 | TransferSyntax11 = LocalEndianExplicit
 45 | TransferSyntax12 = OppositeEndianExplicit
 46 | TransferSyntax13 = LittleEndianImplicit
 47 | 
 48 | [Uncompressed]
 49 | TransferSyntax1  = LocalEndianExplicit
 50 | TransferSyntax2  = OppositeEndianExplicit
 51 | TransferSyntax3  = LittleEndianImplicit
 52 | 
 53 | [UncompressedOrZlib]
 54 | TransferSyntax1  = DeflatedLittleEndianExplicit
 55 | TransferSyntax2  = LocalEndianExplicit
 56 | TransferSyntax3  = OppositeEndianExplicit
 57 | TransferSyntax4  = LittleEndianImplicit
 58 | 
 59 | 
 60 | # ============================================================================
 61 | [[PresentationContexts]]
 62 | # ============================================================================
 63 | 
 64 | [GenericStorageSCP]
 65 | #
 66 | # Don't forget to support the Verification SOP Class.
 67 | #
 68 | PresentationContext1   = VerificationSOPClass\Uncompressed
 69 | #
 70 | # Accept image SOP classes with virtually any transfer syntax we know.
 71 | # Accept non-image SOP classes uncompressed or with zlib compression only.
 72 | #
 73 | PresentationContext2   = ComputedRadiographyImageStorage\AnyTransferSyntax
 74 | PresentationContext3   = CTImageStorage\AnyTransferSyntax
 75 | PresentationContext4   = DigitalIntraOralXRayImageStorageForPresentation\AnyTransferSyntax
 76 | PresentationContext5   = DigitalIntraOralXRayImageStorageForProcessing\AnyTransferSyntax
 77 | PresentationContext6   = DigitalMammographyXRayImageStorageForPresentation\AnyTransferSyntax
 78 | PresentationContext7   = DigitalMammographyXRayImageStorageForProcessing\AnyTransferSyntax
 79 | PresentationContext8   = DigitalXRayImageStorageForPresentation\AnyTransferSyntax
 80 | PresentationContext9   = DigitalXRayImageStorageForProcessing\AnyTransferSyntax
 81 | PresentationContext10  = EnhancedCTImageStorage\AnyTransferSyntax
 82 | PresentationContext11  = EnhancedMRImageStorage\AnyTransferSyntax
 83 | PresentationContext12  = EnhancedXAImageStorage\AnyTransferSyntax   
 84 | PresentationContext13  = EnhancedXRFImageStorage\AnyTransferSyntax
 85 | PresentationContext14  = MRImageStorage\AnyTransferSyntax
 86 | PresentationContext15  = MultiframeGrayscaleByteSecondaryCaptureImageStorage\AnyTransferSyntax
 87 | PresentationContext16  = MultiframeGrayscaleWordSecondaryCaptureImageStorage\AnyTransferSyntax
 88 | PresentationContext17  = MultiframeSingleBitSecondaryCaptureImageStorage\AnyTransferSyntax
 89 | PresentationContext18  = MultiframeTrueColorSecondaryCaptureImageStorage\AnyTransferSyntax
 90 | PresentationContext19  = NuclearMedicineImageStorage\AnyTransferSyntax
 91 | PresentationContext20  = OphthalmicPhotography16BitImageStorage\AnyTransferSyntax
 92 | PresentationContext21  = OphthalmicPhotography8BitImageStorage\AnyTransferSyntax
 93 | PresentationContext22  = RETIRED_NuclearMedicineImageStorage\AnyTransferSyntax
 94 | PresentationContext23  = RETIRED_UltrasoundImageStorage\AnyTransferSyntax
 95 | PresentationContext24  = RETIRED_UltrasoundMultiframeImageStorage\AnyTransferSyntax
 96 | PresentationContext25  = RETIRED_VLImageStorage\AnyTransferSyntax
 97 | PresentationContext26  = RETIRED_VLMultiFrameImageStorage\AnyTransferSyntax
 98 | PresentationContext27  = RETIRED_XRayAngiographicBiPlaneImageStorage\AnyTransferSyntax
 99 | PresentationContext28  = RTImageStorage\AnyTransferSyntax
100 | PresentationContext29  = SecondaryCaptureImageStorage\AnyTransferSyntax
101 | PresentationContext30  = UltrasoundImageStorage\AnyTransferSyntax
102 | PresentationContext31  = UltrasoundMultiframeImageStorage\AnyTransferSyntax
103 | PresentationContext32  = VideoEndoscopicImageStorage\AnyTransferSyntax
104 | PresentationContext33  = VideoMicroscopicImageStorage\AnyTransferSyntax
105 | PresentationContext34  = VideoPhotographicImageStorage\AnyTransferSyntax
106 | PresentationContext35  = VLEndoscopicImageStorage\AnyTransferSyntax
107 | PresentationContext36  = VLMicroscopicImageStorage\AnyTransferSyntax
108 | PresentationContext37  = VLPhotographicImageStorage\AnyTransferSyntax
109 | PresentationContext38  = VLSlideCoordinatesMicroscopicImageStorage\AnyTransferSyntax
110 | #
111 | # the following presentation contexts are for non-image SOP classes
112 | #
113 | PresentationContext44  = AmbulatoryECGWaveformStorage\UncompressedOrZlib
114 | PresentationContext45  = BasicTextSR\UncompressedOrZlib
115 | PresentationContext46  = BasicVoiceAudioWaveformStorage\UncompressedOrZlib
116 | PresentationContext47  = BlendingSoftcopyPresentationStateStorage\UncompressedOrZlib
117 | PresentationContext48  = CardiacElectrophysiologyWaveformStorage\UncompressedOrZlib
118 | PresentationContext49  = ChestCADSR\UncompressedOrZlib
119 | PresentationContext50  = ColorSoftcopyPresentationStateStorage\UncompressedOrZlib
120 | PresentationContext51  = ComprehensiveSR\UncompressedOrZlib
121 | PresentationContext52  = EncapsulatedPDFStorage\UncompressedOrZlib
122 | PresentationContext53  = EnhancedSR\UncompressedOrZlib
123 | PresentationContext54  = GeneralECGWaveformStorage\UncompressedOrZlib
124 | PresentationContext55  = GrayscaleSoftcopyPresentationStateStorage\UncompressedOrZlib
125 | PresentationContext56  = HemodynamicWaveformStorage\UncompressedOrZlib
126 | PresentationContext57  = KeyObjectSelectionDocument\UncompressedOrZlib
127 | PresentationContext58  = MammographyCADSR\UncompressedOrZlib
128 | PresentationContext59  = MRSpectroscopyStorage\UncompressedOrZlib
129 | PresentationContext60  = PETCurveStorage\UncompressedOrZlib
130 | PresentationContext61  = ProcedureLogStorage\UncompressedOrZlib
131 | PresentationContext62  = PseudoColorSoftcopyPresentationStateStorage\UncompressedOrZlib
132 | PresentationContext63  = RawDataStorage\UncompressedOrZlib
133 | PresentationContext64  = RealWorldValueMappingStorage\UncompressedOrZlib
134 | PresentationContext65  = RTBeamsTreatmentRecordStorage\UncompressedOrZlib
135 | PresentationContext66  = RTBrachyTreatmentRecordStorage\UncompressedOrZlib
136 | PresentationContext67  = RTDoseStorage\UncompressedOrZlib
137 | PresentationContext68  = RTPlanStorage\UncompressedOrZlib
138 | PresentationContext69  = RTStructureSetStorage\UncompressedOrZlib
139 | PresentationContext70  = RTTreatmentSummaryRecordStorage\UncompressedOrZlib
140 | PresentationContext71  = SpatialFiducialsStorage\UncompressedOrZlib
141 | PresentationContext72  = SpatialRegistrationStorage\UncompressedOrZlib
142 | PresentationContext73  = StandaloneCurveStorage\UncompressedOrZlib
143 | PresentationContext74  = StandaloneModalityLUTStorage\UncompressedOrZlib
144 | PresentationContext75  = StandaloneOverlayStorage\UncompressedOrZlib
145 | PresentationContext76  = StandaloneVOILUTStorage\UncompressedOrZlib
146 | PresentationContext77  = StereometricRelationshipStorage\UncompressedOrZlib
147 | PresentationContext78  = StoredPrintStorage\UncompressedOrZlib
148 | PresentationContext79  = TwelveLeadECGWaveformStorage\UncompressedOrZlib
149 | PresentationContext80  = XRayRadiationDoseSR\UncompressedOrZlib
150 | 
151 | # ============================================================================
152 | [[Profiles]]
153 | # ============================================================================
154 | 
155 | [Default]
156 | PresentationContexts = GenericStorageSCP
157 | TransferSyntaxes = AnyTransferSyntax 
158 | 


--------------------------------------------------------------------------------
/class_dicom.php:
--------------------------------------------------------------------------------
  1 | 
  4 | http://www.deanvaughan.org/projects/class_dicom_php/
  5 | */
  6 | 
  7 | define('TOOLKIT_DIR', '/usr/local/bin'); // CHANGE THIS IF YOU HAVE DCMTK INSTALLED SOMEWHERE ELSE
  8 | 
  9 | // WINDOWS EXAMPLE
 10 | // define('TOOLKIT_DIR', 'C:/dcmtk/bin');
 11 | 
 12 | ////////////////
 13 | ///////////////
 14 | ///////////////
 15 | // Are we running under Windows?
 16 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
 17 |   define('RUNNING_WINDOWS', 1);
 18 | } 
 19 | else {
 20 |   define('RUNNING_WINDOWS', 0);
 21 | }
 22 | 
 23 | // If we're running under windows change where we look for our binaries.
 24 | // Just add .exe to the end of them.
 25 | if(RUNNING_WINDOWS) {
 26 |   define('BIN_DCMDUMP', TOOLKIT_DIR . '/dcmdump.exe');
 27 |   define('BIN_STORESCU', TOOLKIT_DIR . '/storescu.exe');
 28 |   define('BIN_STORESCP', TOOLKIT_DIR . '/storescp.exe');
 29 |   define('BIN_ECHOSCU', TOOLKIT_DIR . '/echoscu.exe');
 30 |   define('BIN_DCMJ2PNM', TOOLKIT_DIR . '/dcmj2pnm.exe');
 31 |   define('BIN_DCMODIFY', TOOLKIT_DIR . '/dcmodify.exe');
 32 |   define('BIN_DCMCJPEG', TOOLKIT_DIR . '/dcmdjpeg.exe');
 33 |   define('BIN_DCMDJPEG', TOOLKIT_DIR . '/dcmcjpeg.exe');
 34 |   define('BIN_XML2DCM', TOOLKIT_DIR . '/xml2dcm.exe');
 35 |   define('BIN_IMG2DCM', TOOLKIT_DIR . '/img2dcm.exe');
 36 | }
 37 | else {
 38 |   define('BIN_DCMDUMP', TOOLKIT_DIR . '/dcmdump');
 39 |   define('BIN_STORESCU', TOOLKIT_DIR . '/storescu');
 40 |   define('BIN_STORESCP', TOOLKIT_DIR . '/storescp');
 41 |   define('BIN_ECHOSCU', TOOLKIT_DIR . '/echoscu');
 42 |   define('BIN_DCMJ2PNM', TOOLKIT_DIR . '/dcmj2pnm');
 43 |   define('BIN_DCMODIFY', TOOLKIT_DIR . '/dcmodify');
 44 |   define('BIN_DCMCJPEG', TOOLKIT_DIR . '/dcmdjpeg');
 45 |   define('BIN_DCMDJPEG', TOOLKIT_DIR . '/dcmcjpeg');
 46 |   define('BIN_XML2DCM', TOOLKIT_DIR . '/xml2dcm');
 47 |   define('BIN_IMG2DCM', TOOLKIT_DIR . '/img2dcm');
 48 | }
 49 | 
 50 | /*
 51 | $d = new dicom_tag;
 52 | $d->file = 'SOME_IMAGE.dcm';
 53 | $d->load_tags();
 54 | $name = $d->get_tag('0010', '0010');
 55 | */
 56 | 
 57 | class dicom_tag {
 58 | 
 59 |   var $tags = array();
 60 |   var $file = -1;
 61 | 
 62 |   function __construct($file = '') {
 63 |     $this->file = $file;
 64 |     if(file_exists($this->file)) {
 65 |       if(is_dcm($this->file)) {
 66 |         $this->load_tags();
 67 |       }
 68 |     }
 69 |   }
 70 | 
 71 | ### LOAD DICOM TAGS FROM A FILE INTO AN ARRAY ($this->tags). $this->file is the filename of the image.
 72 |   function load_tags() {
 73 |     $file = $this->file;
 74 |     $dump_cmd = BIN_DCMDUMP . " -M +L +Qn $file";
 75 |     $dump = Execute($dump_cmd);
 76 | 
 77 |     if(!$dump) {
 78 |       return(0);
 79 |     }
 80 | 
 81 | #print "$dump\n";
 82 | #exit;
 83 | 
 84 |     $this->tags = array();
 85 | 
 86 |     foreach(explode("\n", $dump) as $line) {
 87 | 
 88 |       $ge = '';
 89 | 
 90 |       $t = preg_match_all("/\((.*)\) [A-Z][A-Z]/", $line, $matches);
 91 |       if(isset($matches[1][0])) {
 92 |         $ge = $matches[1][0];
 93 |         if(!isset($this->tags["$ge"])) {
 94 |           $this->tags["$ge"] = '';
 95 |         }
 96 |       }
 97 | 
 98 |       if(!$ge) {
 99 |         continue;
100 |       }
101 | 
102 |       $val = '';
103 |       $found = 0;
104 |       $t = preg_match_all("/\[(.*)\]/", $line, $matches);
105 |       if(isset($matches[1][0])) {
106 |         $found = 1;
107 |         $val = $matches[1][0];
108 | 
109 |         if(is_array($this->tags["$ge"])) { // Already an array
110 |           $this->tags["$ge"][] = $val;
111 |         }
112 |         else { // Create new array
113 |           $old_val = $this->tags["$ge"];
114 |           if($old_val) {
115 |             $this->tags["$ge"] = array();
116 |             $this->tags["$ge"][] = $old_val;
117 |             $this->tags["$ge"][] = $val;
118 |           }
119 |           else {
120 |             $this->tags["$ge"] = $val;
121 |           }
122 |         }
123 |       }
124 | 
125 |       if(is_array($this->tags["$ge"])) {
126 |         $found = 1;
127 |       }
128 | 
129 |       if(!$found) { // a couple of tags are not in [] preceded by =
130 |         $t = preg_match_all("/\=(.*)\#/", $line, $matches);
131 |         if(isset($matches[1][0])) {
132 |           $found = 1;
133 |           $val = $matches[1][0];
134 |           $this->tags["$ge"] = rtrim($val);
135 |         }
136 |       }
137 | 
138 |       if(!$found) { // a couple of tags are not in []
139 |         $t = preg_match_all("/[A-Z][A-Z] (.*)\#/", $line, $matches);
140 |         if(isset($matches[1][0])) {
141 |           $found = 1;
142 |           $val = $matches[1][0];
143 |           if(strstr($val, '(no value available)')) {
144 |             $val = '';
145 |           }
146 |           $this->tags["$ge"] = rtrim($val);
147 |         }
148 |       }
149 |     }
150 |   }
151 | 
152 | ### AFTER load_tags() HAS BEEN CALLED, USE THIS TO GET A SPECIFIC TAG
153 |   function get_tag($group, $element) {
154 |     $val = '';
155 |     if(isset($this->tags["$group,$element"])) {
156 |       $val = $this->tags["$group,$element"];
157 |     }
158 |     return($val);
159 |   }
160 | 
161 | ### WRITE TAGS INTO AN IMAGE, $tag_arr SHOULD LOOK LIKE:
162 | /*
163 | $tag_arr = array(
164 |   '0010,0010' => 'VAUGHAN^DEAN',
165 |   '0008,0080' => 'DEANLAND, AR'
166 | );
167 | */
168 | ### $this->file is the filename of the image.
169 |   function write_tags($tag_arr) {
170 |     if(!is_array($tag_arr)) {
171 |       return(1);
172 |     }
173 | 
174 |     $str = '';
175 |     foreach($tag_arr as $group => $element) {
176 |       $str .= "-i \"($group)=$element\" ";
177 |     }
178 | 
179 |     $write_cmd = BIN_DCMODIFY . " $str " .
180 |                "-nb \"" . $this->file . "\"";
181 |     $out = Execute($write_cmd);
182 |     if(!$out) {
183 |       return(0);
184 |     }
185 |     else {
186 |       return($out);
187 |     }
188 |   }
189 | 
190 | 
191 | }
192 | 
193 | class dicom_convert {
194 | 
195 |   var $file = '';  
196 |   var $jpg_file = '';
197 |   var $tn_file = '';
198 |   var $jpg_quality = 100;
199 |   var $tn_size = 125;
200 | 
201 |   function __construct($file = '') {
202 |     $this->file = $file;
203 |   }
204 |   
205 | ### Convert a DICOM image to JPEG. $this->file is the filename of the image.
206 | ### $this->jpg_quality is an optional value (0-100) that'll set the quality of the JPEG produced
207 |   function dcm_to_jpg() {
208 | 
209 |     $filesize = 0;
210 | 
211 |     $this->jpg_file = $this->file . '.jpg';
212 |    
213 |     $convert_cmd = BIN_DCMJ2PNM . " +oj +Jq " . $this->jpg_quality . " --use-window 1 \"" . $this->file . "\" \"" . $this->jpg_file . "\"";
214 |     $out = Execute($convert_cmd);
215 | 
216 |     if(file_exists($this->jpg_file)) {
217 |       $filesize = filesize($this->jpg_file);
218 |     }
219 | 
220 |     if($filesize < 10) {
221 |       $convert_cmd = BIN_DCMJ2PNM . " +Wm +oj +Jq " . $this->jpg_quality . " \"" . $this->file . "\" \"" . $this->jpg_file . "\"";
222 |       $out = Execute($convert_cmd);
223 |     }
224 | 
225 |     return($this->jpg_file);
226 | 
227 |   }
228 | 
229 | ### Convert $this->file into a JPEG thumbnail.
230 | ### Optional $this->tn_size will let you change the width of the thumbnail produced
231 |   function dcm_to_tn() {
232 |     $filesize = 0;
233 |     $this->tn_file = $this->file . '_tn.jpg';
234 | 
235 |     $convert_cmd = BIN_DCMJ2PNM . " +oj +Jq 75 +Sxv " . $this->tn_size . " --use-window 1 \"" . $this->file . "\" \"" . $this->tn_file . "\"";
236 |     $out = Execute($convert_cmd);
237 | 
238 |     if(file_exists($this->tn_file)) {
239 |       $filesize = filesize($this->tn_file);
240 |     }
241 | 
242 |     if($filesize < 10) {
243 |       $convert_cmd = BIN_DCMJ2PNM . " +Wm +oj +Jq 75 +Sxv  " . $this->tn_size . " \"" . $this->file . "\" \"" . $this->tn_file . "\"";
244 |       $out = Execute($convert_cmd);
245 |     }
246 | 
247 |     return($this->tn_file);
248 |   }
249 | 
250 | ### This will uncompress $this->file. 
251 | ### Optionally, you can give the output file a different name than the original by passing $new_file
252 |   function uncompress($new_file = '') {
253 |     if(!$new_file) {
254 |       $new_file = $this->file;
255 |     }
256 | 
257 |     $uncompress_cmd = BIN_DCMDJPEG . " \"" . $this->file . "\" \"" . $new_file . "\"";
258 |     $out = Execute($uncompress_cmd);
259 |     return($new_file);
260 |   }
261 | 
262 | // THIS REALLY SHOULD BE EXPANDED TO INCLUDE OTHER COMPRESSION OPTIONS
263 | ### This will JPEG losslessly compress $this->file 
264 | ### Optionally, you can give the output file a different name than the original by passing $new_file
265 |   function compress($new_file = '') {
266 |     if(!$new_file) {
267 |       $new_file = $this->file;
268 |     }
269 | 
270 |     $uncompress_cmd = BIN_DCMCJPEG . " \"" . $this->file . "\" \"" . $new_file . "\"";
271 |     $out = Execute($compress_cmd);
272 |     return($new_file);
273 |   }
274 | 
275 | ### See examples/jpg_to_dcm.php for an example, it'll help things make sense. 
276 | /*
277 | $this->jpg_file is the JPEG you plan on turning into a DICOM file.
278 | 
279 | Make an array that maps the values to the tags you want your DICOM file to contain. Like this:
280 | $arr_info = array(
281 |   '0010,0010' => 'VAUGHAN^DEAN', // Patient Name 
282 |   '0008,0080' => 'DEANLAND, AR'  // Institution
283 | );
284 | You'll actually need to map more fields out to get a usable DICOM file. examples/jpg_to_dcm.php has an example of what's
285 | probably the minimum you need to keep most other DICOM software happy with the files you're producing.
286 | 
287 | Point $this->template towards examples/jpg_to_dcm.xml You'll notice it's a shortened output of dcm2xml. I've put the tag 
288 | name in () where I want the value to go.
289 | 
290 | */
291 |   function jpg_to_dcm($arr_info) {
292 | 
293 |     // USING THE DATA IN OUR ARRAY AND THE TEMPLATE, BUILD AN XML FILE FOR DCMTK
294 |     $xml = file_get_contents($this->template);
295 |     $temp_xml = $this->temp_dir . '/' . date('YmdGis') . rand(0, 30) . '.xml';
296 | 
297 |     foreach($arr_info as $tag => $value) {
298 |       $xml = str_replace("($tag)", $value, $xml);
299 |     }
300 | 
301 |     file_put_contents($temp_xml, $xml);
302 | 
303 |     // Make a DCM file using the XML we just made as the header info.
304 |     $this->file = $this->jpg_file . '.dcm';
305 |     $xml2dcm_cmd = BIN_XML2DCM . " $temp_xml " . $this->file;
306 |     $out = Execute($xml2dcm_cmd);
307 |     if($out) {
308 |       return($out);
309 |     }
310 |     unlink($temp_xml); // NO LONGER NEEDED
311 | 
312 |     // Add the JPEG image to the DCM we just made
313 |     $combine_cmd = BIN_IMG2DCM . " -df " . $this->file . " -stf " . $this->file . " -sef " . $this->file . " \"" . $this->jpg_file . "\" " . $this->file;
314 |     $out = Execute($combine_cmd);
315 |     if($out) {
316 |       return($out);
317 |     }
318 | 
319 |     return($this->file);
320 |   }
321 | 
322 | ### You will want to change $vid_cmd to be applicable to your system
323 |   function multiframe_to_video($format = 'mp4', $framerate = 24, $temp_dir = "./video_temp") {
324 | 
325 |     $want = 7;
326 | 
327 |     $vid_file = basename($this->file) . ".$format";
328 | 
329 |     if(dirname($this->file) == '.') {
330 |       $this->file = dirname(__FILE__) . '/' . $this->file;
331 |     }
332 | 
333 |     if (!file_exists($temp_dir)) {
334 |       mkdir($temp_dir, 0777);
335 |     }
336 | 
337 |     # Split each frame into a jpeg
338 |     $curr_dir = getcwd();
339 |     chdir($temp_dir);
340 |     $split_cmd = BIN_DCMJ2PNM . " +Fa +oj +Jq 100 \"" . $this->file . "\" frame";
341 |     $out = Execute($split_cmd);
342 | 
343 |     if($out) {
344 |       return("$split_cmd: $out");
345 |     }
346 | 
347 |     ## rename our jpegs into something suited for ffmpeg (001, 002, 003, ect)
348 |     $x = 0;
349 | 
350 |     if ($handle = opendir('.')) {
351 |       while (false !== ($file = readdir($handle))) {
352 |         if ($file == '.' || $file == '..') {
353 |           continue;
354 |         }
355 |         if (!strstr($file, '.jpg')) {
356 |           continue;
357 |         }
358 | 
359 |         $new_name = str_replace('frame.', '', $file);
360 |         $l = strlen($new_name);
361 |         $diff = $want - $l;
362 |         while ($diff) {
363 |           $new_name = "0$new_name";
364 |           $diff--;
365 |         }
366 |         if ($file != $new_name) {
367 |           rename($file, $new_name);
368 |         }
369 |         $x++;
370 |       }
371 |       closedir($handle);
372 |     }
373 | 
374 |     if ($x < 10) {
375 |       $framerate = 10;
376 |     }
377 | 
378 |     if(file_exists($vid_file)) {
379 |       unlink($vid_file);
380 |     }
381 | 
382 |     $vid_cmd = "ffmpeg -r $framerate -b 5000k -i %03d.jpg -vcodec libx264 \"$vid_file\"";
383 |     $out = Execute($vid_cmd);
384 | 
385 |     /* This is a special case, probably only useful to me.
386 |         if(strstr($out, 'height not divisible by 2')) {
387 |           print "Running height fix\n";
388 |           unlink($vid_file);
389 |           $out = Execute("mogrify -resize 992x504 *.jpg");
390 |           $vid_cmd = "/usr/local/bin/ffmpeg -r $framerate -b 5000k -i %03d.jpg -vcodec libx264 $vid_file";
391 |           $out = Execute($vid_cmd);
392 |         }
393 |     */
394 | 
395 |     chdir($curr_dir);
396 | 
397 |     return ("$temp_dir/$vid_file");
398 |   }
399 | 
400 | ### SOME DAY...
401 |   function pdf_to_dcm($arr_info) {
402 | 
403 |   }
404 | 
405 |   function pdf_to_dcmcr($arr_info) {
406 | 
407 |   }
408 | 
409 | }
410 | 
411 | 
412 | class dicom_net {
413 | 
414 |   var $transfer_syntax = '';
415 |   var $file = '';
416 | 
417 | ### $port is the tcp port to listen on
418 | ### $dcm_dir is where the DICOM files go after being received. 
419 | ### $handler_script is a program that will be ran after each DICOM file is received. The DICOM image's filename, $dcm_dir, 
420 | ### and the AE titles will be passed via the command line
421 | ### $config_file is the storescp config file. man storescp will get you a run down. The file provided in 
422 | ### examples/store_server_config.cfg will work with all of the common ways of doing things
423 |   function store_server($port, $dcm_dir, $handler_script, $config_file, $debug = 0) {
424 |     $dflag = '';
425 |     if($debug) {
426 |       $dflag = '-v -d ';
427 |     }
428 | 
429 |     system(BIN_STORESCP . " $dflag -dhl -td 20 -ta 20 --fork -xf $config_file Default -od $dcm_dir -xcr \"$handler_script \"#p\" \"#f\" \"#c\" \"#a\"\" $port");
430 |   }
431 | 
432 | ### Performs an echoscu (DICOM ping) on $host $port
433 |   function echoscu($host, $port, $my_ae = 'DEANO', $remote_ae = 'DEANO') {
434 |     $ping_cmd = BIN_ECHOSCU . " -ta 5 -td 5 -to 5 -aet \"$my_ae\" -aec \"$remote_ae\" $host $port";
435 |     $out = Execute($ping_cmd);
436 |     if(!$out) {
437 |       return(0);
438 |     }
439 |     return($out);
440 |   }
441 | 
442 | ### Sends $this_file to $host $port.
443 | ### If $send_batch is enabled it'll send all of the files in the same directory as $this->file in one association
444 |   function send_dcm($host, $port, $my_ae = 'DEANO', $remote_ae = 'DEANO', $send_batch = 0) {
445 | 
446 |     if(!$this->transfer_syntax) {
447 |       $tags = new dicom_tag;
448 |       $tags->file = $this->file;
449 |       $tags->load_tags();
450 |       $this->transfer_syntax = $tags->get_tag('0002', '0010');
451 |     }
452 | 
453 |     $ts_flag = '';
454 |     switch($this->transfer_syntax) {
455 |       case 'JPEGBaseline':
456 |         $ts_flag = '-xy';
457 |       break;
458 |       case 'JPEGExtended:Process2+4':
459 |         $ts_flag = '-xx';
460 |       break;
461 |       case 'JPEGLossless:Non-hierarchical-1stOrderPrediction':
462 |         $ts_flag = '-xs';
463 |       break;
464 |     }
465 | 
466 |     $to_send = $this->file;
467 | 
468 |     if($send_batch) {
469 |       $to_send = dirname($this->file);
470 |       $send_command = BIN_STORESCU . " -ta 10 -td 10 -to 10 $ts_flag -aet \"$my_ae\" -aec $remote_ae $host $port +sd \"$to_send\"";
471 |     }
472 |     else {
473 |       $send_command = BIN_STORESCU . " -ta 10 -td 10 -to 10 $ts_flag -aet \"$my_ae\" -aec $remote_ae $host $port \"$to_send\"";
474 |     }
475 | 
476 |     $out = Execute($send_command); 
477 |     if($out) {
478 |       return($out);
479 |     }
480 |     return(0);
481 | 
482 |   }
483 | 
484 | }
485 | 
486 | ### CAPTURES ALL OF THE GOOD OUTPUTS!
487 | function Execute($command) {
488 | 
489 |   $command .= ' 2>&1';
490 |   $handle = popen($command, 'r');
491 |   $log = '';
492 | 
493 |   while (!feof($handle)) {
494 |     $line = fread($handle, 1024);
495 |     $log .= $line;
496 |   }
497 |   pclose($handle);
498 | 
499 |   return $log;
500 | }
501 | 
502 | ### I'm keeping this outside of the class so it is easier to get to. This may change in the future.
503 | function is_dcm($file) {
504 |   $dump_cmd = BIN_DCMDUMP . " -M +L +Qn $file";
505 |   $dump = Execute($dump_cmd);
506 | 
507 |   if(strstr($dump, 'error')) {
508 |     return(0);
509 |   }
510 |   else if(strstr($dump, 'Modality')) {
511 |     return(1);
512 |   }
513 | 
514 |   return(0);
515 | }
516 | 
517 | 
518 | 
519 | ?>
520 | 


--------------------------------------------------------------------------------