In this tutorial I’m going to post some example code and walk you through converting a DICOM multi-frame image (CINE Loop) into an mp4 video file. I chose MP4 because it works well with Apple and Microsoft products.

You’ll need ffmpeg installed with the ability to do x264. The ffmpeg site has many guides on how to do this. I used this guide for CentOS 6 for this tutorial.

You’ll need a copy of my PHP DICOM class installed.

You’ll need a copy of the example files.

Once you’ve got the prerequisites out of the way, run the commands below to download and run a copy of the example files.

tar zxvf multi-frame-to-mp4.tar.gz
cd Mutli-Frame_to_MP4/
./dcm2mp4.php sample.dcm

Your freshly created MP4 file is ./video_temp/sample.dcm.mp4, a copy is playing below:

Now take a look at dcm2mp4.php, it should be commented well enough to make it easy to understand what it is doing.

This article will cover writing a storage server that is able to receive images, store them on your hard drive, create thumbnails of the images, parse out important header information, and store that header information in a database.

In my continuing effort to show off how handy my PHP DICOM class and the OFFIS DCMTK are, I’ve decided to write a series of articles on how to implement a PACS in PHP.

These articles will be focused on Linux, though I may amend them in the future to cover Windows. They will assume that you have some knowledge of PHP, mySQL, and the Linux command line.

You will need my PHP DICOM class installed. You will also need mySQL installed and have access to add users and databases.

One of the things I dislike about programming books is that they’ll spend pages upon pages showing snippets of code and explaining everything line by line. I’m not going to use that approach, I’m going to walk you through getting the example code running on your computer, testing it, and explaining how it works in a high level fashion. I tried to write the code plainly, simply, and use verbose comments through out explaining what is going on.

Lets get the sample code up and running!

Step 1:

tar xvf PACS_Tutorial.tar.gz
cd PACS_Tutorial/part1
chmod 755 import.php store_server.php send_test_image.php
chmod -R 777 received_images temp

Download all of the sample code and set permissions.

Step 2:

mysql -uroot -p < db.sql

We need to create a database and user for our PACS. The file db.sql will create a user, ‘pacs’, with password ‘pacspassword’, and grant it all privileges to a new database called ‘pacs’. It will then create two tables, studies and images.

If at all possible, don’t change any of this, it’ll make the tutorial a lot less of a headache. If you do change it, open up import.php, and look for mysql_connect. Change the values there as needed.

Step 3:


With that command we’ve launched our storage server on port 1104. Notice that the script didn’t launch in the background? Don’t worry, I’ll cover that later on.

If you don’t want your server running on port 1104, edit store_server.php and its easy enough to change.

The storage server as is doesn’t care about AE titles, its promiscuous and will accept images from anyone.

Step 4:

Since our storage server is using our terminal, leave it running and open a new terminal for the next steps.

store_server.php is going to be receiving your images, after an image is received it will run another script, import.php. import.php will be responsible for moving the image to a safe place on the hard drive, parsing the image’s header information, placing that information into a database, and creating a JPEG thumbnail of the image for later use.

You can test to see if all of this works by sending an image to your computer’s IP address using port 1104. You can make something up for the AE title.

If you don’t have a way to send yourself images, I’ve included a small script that will send your new server one image.


That will send dean.dcm from class_dicom.php’s examples over to your new server.

Once you have sent an image you can switch back to your terminal running store_server.php and see the log entries regarding the image transmission. Among many things the log will show you where the image was saved.

Step 5:

mysql -uroot -p < view_db.sql

Let’s take a look at the database. If all went well the command above should show you the contents of the database; information about the images sent to the server.

There are two tables.

The first table is studies. This table contains information obtained from the image pertaining to the study. Each study can have many images, in example, a chest study could have both a PA and lateral view; one study, two images.

The second table is images. This table contains information specific to an image.

You’ll see there isn’t a field for storing the file name of the image, this is because the file name is easily inferred from database information.

Take a look at this snippet from import.php:

$store_dir = "./received_images/$sent_from_ae/" . $img['year'] . "/" . $img['month'] . "/" . $img['day'] . "/" .

The image is stored in a directory based on the AE title it came from, the appointment date, and the study uid. The image itself uses the SOP instance plus ‘.dcm’ for its file name. Since all of this information is in the database, we can find the file. Later tutorials will go into more detail on this.

Step 6:

Right now, the storage server is stuck running in its own terminal window, if you close the window the storage server stops running, not cool. You’ll want to get it running in the background and you’ll want it to start at boot.

This gets tricky as different flavors of Linux, and even different versions of those flavors, handle this differently. I’ll discuss the three most common approaches. If you have not done so already, control-c in the storage_server.php terminal to stop it.

CentOS 5.6+, Fedora, Red Hat, Ubuntu:

You should have a /etc/init directory. You can place script in this directory that init will use to start/stop and keep running your programs.

start on runlevel [3]
stop on runlevel [!$RUNLEVEL]
console output
exec /home/dean/PACS_Tutorial/part1/store_server.php

Create /init/store_server.conf and add all of that. Be sure to change the path to store_server.php to match your own setup.

‘initctl start store_server’ to start your server


If you don’t have a /etc/init directory, you can always fall back to editing the inittab itself.


Edit /etc/inittab and add this line to the bottom of the file. Be sure to change the path so it points to your copy of store_server.php. Once you’re back at the command line, type ‘init q’. This will reload the inittab and start up store_server.php.

All else fails:

nohup store_server.php

nohup will start store_server.php in the background for you. It will not restart the process if it crashes as the methods above will.

The End?

Now you have a multi-threaded DICOM storage server capable of receiving thousands of studies worth of images everyday. The information it receives is placed into a database for easy access by other programs.

Stay tuned for part two where in I’ll show you how to write a user interface to your PACS.