package ij.plugin; import java.awt.*; import java.awt.image.*; import java.util.Vector; import java.io.*; import ij.*; import ij.process.*; import ij.io.*; import ij.gui.*; /** Writes the XY coordinates and pixel values of all non-background pixels to a tab-delimited text file. Backround is assumed to be the value of the pixel in the upper left corner of the image. */ public class XYCoordinates implements PlugIn { static boolean processStack; static boolean invertY; static boolean suppress; public void run(String arg) { ImagePlus imp = IJ.getImage(); ImageProcessor ip = imp.getProcessor(); int width = imp.getWidth(); int height = imp.getHeight(); double background = ip.getPixelValue(0,0); String bg = " \n"; boolean rgb = imp.getBitDepth()==24; if (rgb) { int c = ip.getPixel(0,0); int r = (c&0xff0000)>>16; int g = (c&0xff00)>>8; int b = c&0xff; bg = r+","+g+","+b; bg = " \n Background value: " + bg + "\n"; } imp.killRoi(); int slices = imp.getStackSize(); String msg = "This plugin writes to a text file the XY coordinates and\n" + "pixel value of all non-background pixels. Backround\n" + "defaults to be the value of the pixel in the upper\n" + "left corner of the image.\n" + bg; GenericDialog gd = new GenericDialog("Save XY Coordinates"); gd.addMessage(msg); int digits = (int)background==background?0:4; if (!rgb) { gd.setInsets(5, 35, 3); gd.addNumericField("Background value:", background, digits); } gd.setInsets(10, 35, 0); gd.addCheckbox("Invert y coordinates off (0 at top of image)", invertY); gd.setInsets(0, 35, 0); gd.addCheckbox("Suppress Log output", suppress); if (slices>1) { gd.setInsets(0, 35, 0); gd.addCheckbox("Process all "+slices+" images", processStack); } gd.showDialog(); if (gd.wasCanceled()) return; if (!rgb) background = gd.getNextNumber(); invertY = gd.getNextBoolean(); suppress = gd.getNextBoolean(); if (slices>1) processStack = gd.getNextBoolean(); else processStack = false; if (!processStack) slices = 1; SaveDialog sd = new SaveDialog("Save Coordinates as Text...", imp.getTitle(), ".txt"); String name = sd.getFileName(); if (name == null) return; String directory = sd.getDirectory(); PrintWriter pw = null; try { FileOutputStream fos = new FileOutputStream(directory+name); BufferedOutputStream bos = new BufferedOutputStream(fos); pw = new PrintWriter(bos); } catch (IOException e) { IJ.write("" + e); return; } IJ.showStatus("Saving coordinates..."); int count = 0; float v; int c,r,g,b; int type = imp.getType(); ImageStack stack = imp.getStack(); for (int z=0; z<slices; z++) { if (slices>1) ip = stack.getProcessor(z+1); String zstr = slices>1?z+"\t":""; for (int i=0; i<height; i++) { int y = invertY?i:height-1-i; for (int x=0; x<width; x++) { v = ip.getPixelValue(x,y); if (v!=background) { if (type==ImagePlus.GRAY32) pw.println(x+"\t"+(invertY?y:height-1-y)+"\t"+zstr+v); else if (rgb) { c = ip.getPixel(x,y); r = (c&0xff0000)>>16; g = (c&0xff00)>>8; b = c&0xff; pw.println(x+"\t"+(invertY?y:height-1-y)+"\t"+zstr+r+"\t"+g+"\t"+b); } else pw.println(x+"\t"+(invertY?y:height-1-y)+"\t"+zstr+(int)v); count++; } } // x if (slices==1&&y%10==0) IJ.showProgress((double)(height-y)/height); } // y if (slices>1) IJ.showProgress(z+1, slices); String img = slices>1?"-"+(z+1):""; if (!suppress) IJ.log(imp.getTitle() + img+": " + count + " pixels (" + IJ.d2s(count*100.0/(width*height)) + "%)\n"); count = 0; } // z IJ.showProgress(1.0); IJ.showStatus(""); pw.close(); } }