/*=========================================================================
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");
}
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" );
}
}