Tuesday, March 25, 2008

Converting DICOM to JPEG using dcm4che 2

Hi Folks,

Sorry, I was quite busy these days, weeks, months :) Now, I can share with you how to convert any Dicom image to Jpeg using the amazing dcm4che 2.0 toolkit. I've spent a lot of time trying to figure out the magic of dcm4che and I've got some stuff that will be posted later.However, the best way to learn dcm4che is studying its utilities apps, so dcm2jpg is the one you must have a look. From now on let's just see how to perform the conversion.

First, you have to download the latest version of dcm4che libraries. Also, you'll need the JAI ImageIO Toolkit in order to quickly read pixel data from Dicom images. And if you don't have any java editor get the best one: Eclipse. You are supposed to know basic java programming, the Eclipse environment and some Dicom stuff.

Lets start. Open your Eclipse IDE and choose File > New > Java Project. Name it myDicomToJpeg. The next step is to create a new class, so right-click the src package and select New > Class. Enter DicomToJpeg for class name and select the main method option. You'll get something like this:

public class DicomToJpeg {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}

In order to use dcm4che classes we have to configure the project's build path. Right-click the project's main folder and select Properties. Select the Java Build Path option. Under Libraries tab we'll find the Add External Jars button. Click on it to select all dcm4che jar files and all JAI ImageIO jar files. Now our project is able to work with dcm4che.

Write the following line inside the main's body. This is our Dicom file:

File myDicomFile = new File("c:/dicomImage.dcm");

Then let's declare what will be our Jpeg image:

BufferedImage myJpegImage = null;

The following line returns an Iterator containing all currently registered ImageReaders that claim to be able to decode the named format (e.g., "DICOM", "jpeg", "tiff").

Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");

The java documentation says an ImageReader object are normally instantiated by the service provider interface (SPI) class for the specific format. Service provider classes (e.g., instances of ImageReaderSpi) are registered with the IIORegistry, which uses them for format recognition and presentation of available format readers and writers. So let's get our ImageReader object.

ImageReader reader = (ImageReader) iter.next();

If you check carefully dcm4che libraries you'll find some specific imageio packages. That's where it keeps the secret of reading Dicom pixel data. Therefore, our ImageReader object is now an instance of a specific SPI class for the Dicom format.

In the following line we get parameters for reading the Dicom image. The java documentation says an ImageReadParam class describe how a stream is to be decoded. Instances of this class or its subclasses are used to supply prescriptive "how-to" information to instances of ImageReader.

DicomImageReadParam param = (DicomImageReadParam) reader.getDefaultReadParam();

Before read all pixel data we have to create an ImageInputStream object for use by our ImageReader object. Note that this input stream has our Dicom file as a parameter. As this process throws an IOException it must be between a try-catch block.

Now all we have to do is to call the read() method from our ImageReader object together with our prescriptive Dicom parameters. The result is a new BufferedImage filled with Dicom pixel data. Pretty easy, hun :)

try {
ImageInputStream iis = ImageIO.createImageInputStream(myDicomFile);
reader.setInput(iis, false);
myJpegImage = reader.read(0, param);
iis.close();

That's it! We read the Dicom image into our myJpegImage object. The following lines just test if we really succeeded. If not, we just print a message.

if (myJpegImage == null) {
System.out.println("\nError: couldn't read dicom image!");
return;
}

You may be asking: ok, how do I get my Jpeg file? The answer is in the following lines. We firstly need to create a Jpeg file that will be sent to an OutputStream to be saved. Then, the JPEGImageEncoder object is responsible for encoding our Jpeg image into this output. When we close the OutputStream our Jpeg file is saved. We're done!!

File myJpegFile = new File("c:/jpegImage.jpg");
OutputStream output = new BufferedOutputStream(new FileOutputStream(myJpegFile));
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(output);
encoder.encode(myJpegImage);
output.close();

Finally, if our try to read the image failed, we probably got an exception. So let's handle it printing a message.

}
catch(IOException e) {
System.out.println("\nError: couldn't read dicom image!"+ e.getMessage());
return;
}

Have a nice day! Hope it helps :)

Samuel.