/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * Simple example showing how to bind a custom Observer to the Scanner in response * to ProgressEvent * If found, icons will be extracted or else they will be generated and save as PNG * * Compilation: * $ CLASSPATH=gdcm.jar javac ../../gdcm/Examples/Java/ScanDirectory.java -d . * * Usage: * $ LD_LIBRARY_PATH=. CLASSPATH=gdcm.jar:. java ScanDirectory gdcmData */ import gdcm.*; import gdcm.Reader; import gdcm.LookupTable; import java.io.File; import java.io.*; import java.awt.image.*; import javax.imageio.ImageIO; public class ScanDirectory { public static class MyWatcher extends SimpleSubjectWatcher { public MyWatcher(Subject s) { super(s,"Override String"); } protected void ShowProgress(Subject caller, Event evt) { ProgressEvent pe = ProgressEvent.Cast(evt); System.out.println( "This is my progress: " + pe.GetProgress() ); } } public static byte[] GetAsByte(Bitmap input) { long len = input.GetBufferLength(); byte[] buffer = new byte[ (int)len ]; PhotometricInterpretation pi = input.GetPhotometricInterpretation(); if( pi.GetType() == PhotometricInterpretation.PIType.MONOCHROME1 ) { ImageChangePhotometricInterpretation icpi = new ImageChangePhotometricInterpretation(); icpi.SetInput( input ); icpi.SetPhotometricInterpretation( new PhotometricInterpretation( PhotometricInterpretation.PIType.MONOCHROME2 ) ); if( icpi.Change() ) { Bitmap output = icpi.GetOutput(); output.GetArray( buffer ); } return buffer; } else { input.GetArray( buffer ); return buffer; } } public static short[] GetAsShort(Bitmap input) { long len = input.GetBufferLength(); // length in bytes short[] buffer = new short[ (int)len / 2 ]; PhotometricInterpretation pi = input.GetPhotometricInterpretation(); if( pi.GetType() == PhotometricInterpretation.PIType.MONOCHROME1 ) { ImageChangePhotometricInterpretation icpi = new ImageChangePhotometricInterpretation(); icpi.SetInput( input ); icpi.SetPhotometricInterpretation( new PhotometricInterpretation( PhotometricInterpretation.PIType.MONOCHROME2 ) ); if( icpi.Change() ) { Bitmap output = icpi.GetOutput(); output.GetArray( buffer ); } return buffer; } else { input.GetArray( buffer ); return buffer; } } public static boolean WritePNG(Bitmap input, String outfilename ) { int imageType = BufferedImage.TYPE_CUSTOM; PixelFormat pf = input.GetPixelFormat(); PhotometricInterpretation pi = input.GetPhotometricInterpretation(); // We need to handle both public and private icon // It could well be that we are getting an RGB Icon or 16 bits Icon: ColorModel colorModel = null; if( pf.GetSamplesPerPixel() == 1 ) { if( pi.GetType() == PhotometricInterpretation.PIType.MONOCHROME1 || pi.GetType() == PhotometricInterpretation.PIType.MONOCHROME2 ) { if( pf.GetScalarType() == PixelFormat.ScalarType.UINT8 ) { imageType = BufferedImage.TYPE_BYTE_GRAY; } else if( pf.GetScalarType() == PixelFormat.ScalarType.UINT12 ) { imageType = BufferedImage.TYPE_USHORT_GRAY; } else if( pf.GetScalarType() == PixelFormat.ScalarType.UINT16 ) { imageType = BufferedImage.TYPE_USHORT_GRAY; } } else if( pi.GetType() == PhotometricInterpretation.PIType.PALETTE_COLOR ) { LookupTable lut = input.GetLUT(); long rl = lut.GetLUTLength( LookupTable.LookupTableType.RED ); byte[] rbuf = new byte[ (int)rl ]; long rl2 = lut.GetLUT( LookupTable.LookupTableType.RED, rbuf ); assert rl == rl2; long gl = lut.GetLUTLength( LookupTable.LookupTableType.GREEN ); byte[] gbuf = new byte[ (int)gl ]; long gl2 = lut.GetLUT( LookupTable.LookupTableType.GREEN, gbuf ); assert gl == gl2; long bl = lut.GetLUTLength( LookupTable.LookupTableType.BLUE ); byte[] bbuf = new byte[ (int)bl ]; long bl2 = lut.GetLUT( LookupTable.LookupTableType.BLUE, bbuf ); assert bl == bl2; colorModel = new IndexColorModel(8, (int)rl, rbuf, gbuf, bbuf); // For code below imageType = BufferedImage.TYPE_BYTE_GRAY; } } else if( pf.GetSamplesPerPixel() == 3 ) { if( pf.GetScalarType() == PixelFormat.ScalarType.UINT8 ) { // FIXME should be TYPE_3BYTE_RGB imageType = BufferedImage.TYPE_3BYTE_BGR; } } //System.out.println( "pf: " + pf.toString() ); //System.out.println( "pi: " + pi.toString() ); long width = input.GetDimension(0); long height = input.GetDimension(0); BufferedImage bi; if( pi.GetType() == PhotometricInterpretation.PIType.PALETTE_COLOR ) { bi = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster((int)width, (int)height), false, null); } else { bi = new BufferedImage((int)width,(int)height,imageType); } WritableRaster wr = bi.getRaster(); //System.out.println( "imagetype: " + imageType ); if( imageType == BufferedImage.TYPE_BYTE_GRAY || imageType == BufferedImage.TYPE_3BYTE_BGR ) { byte[] buffer = GetAsByte( input ); wr.setDataElements (0, 0, (int)width, (int)height, buffer); } else if( imageType == BufferedImage.TYPE_USHORT_GRAY ) { short[] buffer = GetAsShort( input ); wr.setDataElements (0, 0, (int)width, (int)height, buffer); } File outputfile = new File( outfilename ); try { ImageIO.write(bi, "png", outputfile); } catch (IOException e) { return false; } return true; } public static void main(String[] args) throws Exception { String directory = args[0]; Directory d = new Directory(); long nfiles = d.Load( directory, true ); if(nfiles == 0) { throw new Exception("No files found"); } // System.out.println( "Files:\n" + d.toString() ); FilenamesType fns = d.GetFilenames(); //Scanner s = new Scanner(); SmartPtrScan sscan = Scanner.New(); Scanner s = sscan.__ref__(); //SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(s, "MySimple"); MyWatcher watcher = new MyWatcher(s); Tag[] tagarray = { new Tag(0x0010, 0x0010), // PatientName new Tag(0x0010, 0x0020), // PatientID new Tag(0x0010, 0x0030), // PatientBirthDate new Tag(0x0010, 0x0040), // PatientSex new Tag(0x0010, 0x1010), // PatientAge new Tag(0x0020, 0x000d), // StudyInstanceUID new Tag(0x0020, 0x0010), // StudyID new Tag(0x0008, 0x0020), // StudyDate new Tag(0x0008, 0x1030), // StudyDescription new Tag(0x0020, 0x000e), // SeriesInstanceUID new Tag(0x0020, 0x0011), // SeriesNumber new Tag(0x0008, 0x0021), // SeriesDate new Tag(0x0008, 0x103e), // SeriesDescription new Tag(0x0008, 0x0090), // ReferringPhysicianName new Tag(0x0008, 0x0060), // Modality new Tag(0x0054, 0x0400), // ImageID ?? Should be Instance number ?? new Tag(0x0008, 0x0018), // SOPInstanceUID new Tag(0x0008, 0x0032), // AcquisitionTime new Tag(0x0008, 0x0033), // ContentTime new Tag(0x0020, 0x0013), // InstanceNumber new Tag(0x0020, 0x1041), // SliceLocation new Tag(0x0018, 0x0050), // SliceThickness ?? Eg. Enhanced MR Image Storage new Tag(0x0008, 0x0080), // InstitutionName new Tag(0x0028, 0x1050), // WindowCenter new Tag(0x0028, 0x1051), // WindowWidth }; for( Tag t : tagarray ) { //System.out.println( "Tag: " + t.toString() ); s.AddTag( t ); } boolean b = s.Scan( fns ); if(!b) { throw new Exception("Could not scan"); } String fn0 = fns.get(0); TagToValue mappings = s.GetMapping( fn0 ); System.out.println( "mappings size: " + mappings.size() ); for( Tag tag : tagarray ) { if( mappings.has_key( tag ) ) { String val = mappings.get( tag ); System.out.println( "tag/val: " + tag + "->" + val ); } } for( long idx = 0; idx < fns.size(); ++idx ) { Reader r = new Reader(); String fn = fns.get( (int)idx ); String outfn = fn + ".png"; r.SetFileName( fn ); TagSetType tst = new TagSetType(); tst.insert( new Tag(0x7fe0,0x10) ); b = r.ReadUpToTag( new Tag(0x88,0x200), tst ); UIntArrayType dims = ImageHelper.GetDimensionsValue( r.GetFile() ); if( b ) { IconImageFilter iif = new IconImageFilter(); System.out.println( "Processing: " + fn ); iif.SetFile( r.GetFile() ); b = iif.Extract(); if( b ) { Bitmap icon = iif.GetIconImage(0); WritePNG(icon, outfn); } else { ImageReader ir = new ImageReader(); ir.SetFileName( fn ); if( ir.Read() ) { Image img = ir.GetImage(); StringFilter sf = new StringFilter(); sf.SetFile( r.GetFile() ); String strval = sf.ToString( new Tag(0x0028,0x0120) ); IconImageGenerator iig = new IconImageGenerator(); iig.SetPixmap( img ); iig.AutoPixelMinMax( true ); try { double val = Double.parseDouble( strval ); iig.SetOutsideValuePixel( val ); } catch ( NumberFormatException e) { } iig.ConvertRGBToPaletteColor( false ); long idims[] = { 128, 128}; iig.SetOutputDimensions( idims ); iig.Generate(); Bitmap icon = iig.GetIconImage(); WritePNG(icon, outfn); } } } } System.out.println( "Scan:\n" + s.toString() ); System.out.println( "success" ); } }