import java.awt.*; import java.awt.event.*; import java.io.*; import ij.*; import ij.io.*; import ij.plugin.PlugIn; //This can open the Hamamatsu photonics IMG file. //With the modified HandleExtraFileTypes.java, Drag&Drop can be used to open the file. //This plugin was modified from the plugin (OpenSPE_.java) to open the SPE files. // // Satoshi Matsuyama (Osaka Univ.) // matsuyama@prec.eng.osaka-u.ac.jp public class OpenIMG_ implements PlugIn { private static int HeaderSize=10240; //2593; //この値は後で正確に決める.機種によって違うみたい.final修飾子をつけたら変更不可となる private static int ImageWidth; private static int ImageHeight; private static int ImageByte; public void run(String arg) { OpenDialog od = new OpenDialog("Open IMG...", arg); String file = od.getFileName(); if (file == null) return; String directory = od.getDirectory(); ImagePlus imp = open(directory, file); if (imp != null ) { imp.show(); } else { IJ.showMessage("Open IMG...", "Failed."); } } public static ImagePlus open(String directory, String file) { File f = new File(directory, file); try { //ヘッダ調べる FileInputStream in = new FileInputStream(f); byte[] h = new byte[HeaderSize]; in.read(h, 0, h.length); //バイト配列を文字に変換 String result = new String(h, "UTF-8"); //IJ.showMessage("check", result); //ヘッダの特定箇所を検索して抜き出す int index = result.indexOf("Prop_ImageWidth="); index += "Prop_ImageWidth=".length(); if (result.charAt(index+4) == '\u002C') { //\u002Cは","を意味する ImageWidth=Integer.parseInt(result.substring(index,index+4)); //1000〜9999 } else if (result.charAt(index+3) == '\u002C') { ImageWidth=Integer.parseInt(result.substring(index,index+3)); //100〜999 } else if (result.charAt(index+5) == '\u002C') { ImageWidth=Integer.parseInt(result.substring(index,index+5)); //10000〜99999 } else if (result.charAt(index+2) == '\u002C') { ImageWidth=Integer.parseInt(result.substring(index,index+2)); //10〜99 } else { IJ.showMessage("Error","Incorrect width!"); } //IJ.showMessage("check", "width=" + String.valueOf(ImageWidth)); index = result.indexOf("Prop_ImageHeight="); index += "Prop_ImageHeight=".length(); if (result.charAt(index+4) == '\u002C') { ImageHeight=Integer.parseInt(result.substring(index,index+4)); //1000〜9999 } else if (result.charAt(index+3) == '\u002C') { ImageHeight=Integer.parseInt(result.substring(index,index+3)); //100〜999 } else if (result.charAt(index+5) == '\u002C') { ImageHeight=Integer.parseInt(result.substring(index,index+5)); //10000〜99999 } else if (result.charAt(index+2) == '\u002C') { ImageHeight=Integer.parseInt(result.substring(index,index+2)); //10〜99 } else { IJ.showMessage("Error","Incorrect height!"); } //IJ.showMessage("check", "height=" + String.valueOf(ImageHeight)); index = result.indexOf("BytesPerPixel="); index += "BytesPerPixel=".length(); ImageByte=Integer.parseInt(result.substring(index,index+1)); //IJ.showMessage("check", "imagebyte=" + String.valueOf(ImageByte)); //ヘッダサイズを正確に求める.CMOS,CCDによってヘッダサイズが違うみたい HeaderSize=(int)f.length()-ImageWidth*ImageHeight*ImageByte; //length()で得られるのはlong型.キャストする. //IJ.showMessage("check", "header=" + String.valueOf(HeaderSize)); //データ本体を開く FileInfo fi = new FileInfo(); fi.directory = directory; fi.fileFormat = fi.RAW; fi.fileName = file; //1ピクセルのByte数を考慮させる if (ImageByte == 1) { fi.fileType = FileInfo.GRAY8; //8ビット(1バイト) } else if (ImageByte == 2) { fi.fileType = FileInfo.GRAY16_UNSIGNED; //16ビット(2バイト),signed(符号有),unsigned(符号無). } else if (ImageByte == 4) { fi.fileType = FileInfo.GRAY32_UNSIGNED; //32ビット(4バイト),signed(符号有),unsigned(符号無). } else { IJ.showMessage("Error","The file cannot be opened!"); return null; } fi.gapBetweenImages = 0; fi.height = ImageHeight; fi.intelByteOrder = true; //これ大事.最下位の桁から順番に数字が格納されているという意味.img,speともにtrueでOK. fi.nImages = 1; //画像の数,2以上はスタックになると思われる fi.offset = HeaderSize; //ヘッダの数,バイト単位.この部分を飛ばしてくれる. fi.width = ImageWidth; FileOpener fo = new FileOpener(fi); ImagePlus imp = fo.open(false); IJ.showStatus(""); return imp; } catch (IOException e) { IJ.error("An error occured reading the file.\n \n" + e); IJ.showStatus(""); return null; } } }