Saturday 25 January 2014

DicomMultiframePlayer in JAVA

package packageTestDcm4che3;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;

import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.dcm4che.imageio.plugins.dcm.DicomImageReadParam;
import org.dcm4che.imageio.plugins.dcm.DicomImageReader;

/**
 * Plays a multiframe DICOM instance.
 *
 * @author dimitri PIANETA
 *
 * <p>The code for this came from <a href="http://samucs.blogspot.com" target="_blank">http://samucs.blogspot.com</a>
 *    and was dated 6-January-2010.</p>
 *
 * <p> code modification 14 January 2014 for dcm4che3 <p>
 */   
public class DicomMultiframePlayer extends JFrame implements ActionListener, Runnable {
   
    private static final long serialVersionUID = 1L;
    private JLabel fileLabel;
    /**
     * Will contain name of file to be read.
     */
    private JTextField fileField;
    /**
     * Triggers process for selecting file to be read.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnChoose;
    /**
     * Starts playing of images.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnPlay;
    /**
     * Pauses playing of images.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnPause;
    /**
     * Halts playing of images.
     * @see #actionPerformed(ActionEvent)
     */
    private JButton btnStop;
    private JButton btnExit;   
    private Vector<BufferedImage> images;
    private ImagePanel imagePanel;   
    private boolean stop;
    private int currentFrame;
   
       
        private int frame = 1;

       
       
       
          private final ImageReader imageReader =
            ImageIO.getImageReadersByFormatName("DICOM").next();
       
       
    public DicomMultiframePlayer() {
        super("DICOM Multiframe Player using dcm4che - by samucs-dev");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().setLayout(new BorderLayout());
       
        images = new Vector<BufferedImage>();
        imagePanel = new ImagePanel();
       
        fileLabel = new JLabel("File:");
        fileField = new JTextField(30);
        btnChoose = this.createJButton(25, 25, "...");
       
        btnPlay = this.createJButton(80,25,"Play");
        btnPause = this.createJButton(80,25,"Pause");
        btnStop = this.createJButton(80,25,"Stop");       
        btnExit = this.createJButton(80,25,"Exit");
        btnPause.setEnabled(false);
        btnStop.setEnabled(false);
       
        JPanel panelNorth = new JPanel();
        panelNorth.add(fileLabel);
        panelNorth.add(fileField);
        panelNorth.add(btnChoose);
       
        JPanel panelSouth = new JPanel();
        panelSouth.add(btnPlay);
        panelSouth.add(btnPause);
        panelSouth.add(btnStop);
        panelSouth.add(btnExit);
       
        this.getContentPane().add(panelNorth, BorderLayout.NORTH);
        this.getContentPane().add(imagePanel, BorderLayout.CENTER);
        this.getContentPane().add(panelSouth, BorderLayout.SOUTH);
       
        this.setSize(new Dimension(500,500));
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
    /**
     * Plays the frames in order.
     *
     * <p>I removed the Override annotation.</p>
     */
    // @Override
    public void run() {
        while(true) {
            if (!btnPlay.isEnabled()) {               
                if (stop) break;               
                currentFrame++;
                if (currentFrame == images.size())
                    currentFrame = 0;
                imagePanel.setImage(images.get(currentFrame));               
                try {
                    Thread.sleep(70);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * Detects clicking of button and carries out appropriate action.
     *
     * <p>I removed the Override annotation.</p>
     */
    // @Override
    public void actionPerformed(ActionEvent e) {       
        if (e.getSource().equals(btnChoose)) {
            JFileChooser chooser = new JFileChooser();
            int action = chooser.showOpenDialog(this);
            switch(action) {
                case JFileChooser.APPROVE_OPTION:
                    this.openFile(chooser.getSelectedFile());
                    break;
                case JFileChooser.CANCEL_OPTION:
                    return;
            }
        }       
        if (e.getSource().equals(btnPlay)) {
            btnPlay.setEnabled(false);
            btnPause.setEnabled(true);
            btnStop.setEnabled(true);
            stop = false;
            new Thread(this).start();           
        }
        if (e.getSource().equals(btnPause)) {
            btnPlay.setEnabled(true);
            btnPause.setEnabled(false);
            btnStop.setEnabled(true);
            stop = false;
        }
        if (e.getSource().equals(btnStop)) {
            btnPlay.setEnabled(true);
            btnPause.setEnabled(false);
            btnStop.setEnabled(false);
            stop = true;
            currentFrame = 0;
            imagePanel.setImage(images.get(0));           
        }
        if (e.getSource().equals(btnExit)) {
            System.exit(0);
        }
    }
    /**
     * Creates JButton objects on window.
     * @param width width of button in pixels.
     * @param height height of button in pixels
     * @param text text to appear in button
     * @return JButton object
     */
    private JButton createJButton(int width, int height, String text) {
        JButton b = new JButton(text);
        b.setMinimumSize(new Dimension(width, height));
        b.setMaximumSize(new Dimension(width, height));
        b.setPreferredSize(new Dimension(width, height));
        b.addActionListener(this);
        return b;
    }
    /**
     * Reads the contents of the dicom file
     * @param file file to be opened
     * @see org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReaderSpi
     * @see org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReader
     */
    private void openFile(File file) {
        images.clear();
        try {
           
                   
                       
            int numFrames =setNumber(file);
            //System.out.println("DICOM image has "+ numFrames +" frames...");           
            System.out.println("Extracting frames...");
            for (int i=0; i < numFrames; i++) {
                     
                       
                          
                BufferedImage img =  chargeImageDicomBufferise(file,i);
                images.add(img);
                System.out.println(" > Frame "+ (i+1));
            }           
            System.out.println("Finished.");
        } catch(Exception e) {
            e.printStackTrace();
            imagePanel.setImage(null);
            return;
        }
        stop = false;
        currentFrame = 0;
        imagePanel.setImage(images.get(0));
    }

     
       
        /**
         * Building BufferingImage
         * @param file : input file
         * @param value : number frame
         * @return
         * @throws IOException
         */
       
        public BufferedImage chargeImageDicomBufferise(File file, int value) throws IOException  {

                Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");//sp?cifie l'image

                              
                         

              ImageReader readers = iter.next();//on se d?place dans l'image dicom

         DicomImageReadParam   param1 =  (DicomImageReadParam) readers.getDefaultReadParam();//return DicomImageReadParam
               //    Adjust the values of Rows and Columns in it and add a Pixel Data attribute with the byte array from the DataBuffer of the scaled Raster

                ImageInputStream iis = ImageIO.createImageInputStream(file);

             readers.setInput(iis, false);//sets the input source to use the given ImageInputSteam or other  Object

               BufferedImage image = readers.read(value,param1);//BufferedImage image = reader.read(frameNumber, param); frameNumber = int qui est l'imageIndex
                System.out.println(image);//affichage au terminal des caract?res de l'image

                readers.dispose();//Releases all of the native sreen resources used by this Window, its subcomponents, and all of its owned children
              return  image;

            }
   
         /**
 *  Find number frame
 * @param file : input file
 * @return numbre frame in Dicom
 * @throws IOException
 */
   public int setNumber(File file) throws IOException  {

            /* Parcourt le fichier dicom*/
             Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");//sp?cifie l'image
           ImageReader readers = (ImageReader)iter.next();//on se d?place dans l'image dicom

            DicomImageReadParam   param1=  (DicomImageReadParam) readers.getDefaultReadParam();//return DicomImageReadParam
           //    Adjust the values of Rows and Columns in it and add a Pixel Data attribute with the byte array from the DataBuffer of the scaled Raster

            ImageInputStream iis = ImageIO.createImageInputStream(file);//cr?ation du fichier image


           readers.setInput(iis, false);//sets the input source to use the given ImageInputSteam or other  Object

            //iis.close();
            int  number = readers.getNumImages(true);//numberOfFrame on a "readers" qui doit ?tre DicomImage
            System.out.println(number);//return NumberOfFrame (Tag : (0028, 0008))
           return  number;
        }
   
   
   
    private class ImagePanel extends JPanel {
        private static final long serialVersionUID = 1L;
        private BufferedImage image;
        private int frame;
        public ImagePanel() {
            super();
            this.setPreferredSize(new Dimension(1024,1024));
            this.setBackground(Color.black);           
        }
        public void setImage(BufferedImage image) {
            this.image = image;
            this.updateUI();
        }
        @Override
        public void paint(Graphics g) {
            if (this.image != null) {
                g.drawImage(this.image, 0, 0, image.getWidth(), image.getHeight(), null);
            }
        }
   
        };

    public static void main(String[] args) {
        new DicomMultiframePlayer();
    }

}

No comments: