4 import java.awt.image.*;
11 import ij.plugin.filter.Analyzer;
21 public class ImagePlus implements ImageObserver, Measurements {
24 public static final int GRAY8 = 0;
51 public String
unit =
"pixel";
60 protected ImageProcessor ip;
64 private FileInfo fileInfo;
67 private int imageType =
GRAY8;
68 private int currentSlice;
70 protected boolean locked =
false;
71 private static int currentID = -1;
73 private static Component comp;
74 private boolean imageLoaded;
75 private int imageUpdateY, imageUpdateW;
76 private Properties properties;
77 private long startTime;
78 private Calibration calibration;
79 private static Calibration globalCalibration;
80 private boolean activated;
81 private boolean ignoreFlush;
82 private boolean errorLoadingImage;
83 protected ImageCanvas imageCanvas;
112 Opener opener =
new Opener();
114 boolean isURL = pathOrURL.indexOf(
"://")>0;
116 imp = opener.openURL(pathOrURL);
118 imp = opener.openImage(pathOrURL);
124 this.url = pathOrURL;
134 public synchronized boolean lock() {
138 if (
IJ.macroRunning()) {
144 if (
IJ.debugMode)
IJ.
log(title +
": lock");
156 if (
IJ.debugMode)
IJ.
log(title +
": lock silently");
164 if (
IJ.debugMode)
IJ.
log(title +
": unlock");
167 private void waitForImage(Image img) {
174 if (!comp.prepareImage(img,
this)) {
176 while (!imageLoaded && !errorLoadingImage) {
179 if (imageUpdateW>1) {
180 progress = (double)imageUpdateY/imageUpdateW;
181 if (!(progress<1.0)) {
182 progress = 1.0 - (progress-1.0);
183 if (progress<0.0) progress = 0.9;
185 IJ.showProgress(progress);
188 IJ.showProgress(1.0);
197 ij.getContentPane().repaint();
201 public void draw(
int x,
int y,
int width,
int height){
202 ImageCanvas ic = getCanvas();
203 double mag = ic.getMagnification();
206 width = (int)(width*mag);
207 height = (int)(height*mag);
208 ic.repaint(x, y, width, height);
217 getCanvas().setImageUpdated();
241 img = ip.createImage();
252 public void show(String statusMessage) {
253 ij.setImagePlus(
this);
264 if (img==null && ip!=null)
265 img = ip.createImage();
279 errorLoadingImage =
false;
281 if (errorLoadingImage)
282 throw new IllegalStateException (
"Error loading image");
284 int newWidth = img.getWidth(ij);
285 int newHeight = img.getHeight(ij);
286 boolean dimensionsChanged = (newWidth!=width) || (newHeight!=height);
292 if (lut.getMapSize() > 0) {
301 this.img = ip.createImage();
307 setProcessor2(title, ip);
310 void setProcessor2(String title, ImageProcessor ip) {
313 if (ij!=null) ip.setProgressBar(ij.getProgressBar());
315 boolean dimensionsChanged = width!=ip.getWidth() || height!=ip.getHeight();
316 if (dimensionsChanged)
319 if (ip instanceof ByteProcessor)
323 else if (ip instanceof ShortProcessor)
331 width = ip.getWidth();
332 height = ip.getHeight();
352 void setupProcessor() {
354 if (ip == null || ip instanceof ByteProcessor) {
355 ip =
new ColorProcessor(
getImage());
356 if (
IJ.debugMode)
IJ.
log(title +
": new ColorProcessor");
359 else if (ip==null || (ip instanceof ColorProcessor)) {
361 if (IJ.debugMode) IJ.log(title +
": new ByteProcessor");
363 if (roi!=null && roi.isArea())
364 ip.setRoi(roi.getBounds());
369 public boolean isProcessor() {
377 if (ip==null && img==null)
380 ip.setLineWidth(Line.getWidth());
383 ip.setProgressBar(ij.getProgressBar());
391 if (ip!=null && !locked) {
392 if (ip!=null &&
IJ.debugMode)
IJ.
log(title +
": trimProcessor");
393 ip.setPixels(ip.getPixels());
405 if (ip!=null) ip.resetRoi();
408 ImageProcessor mask = roi.getMask();
413 ip.setRoi(roi.getBounds());
445 public ImageStatistics
getStatistics(
int mOptions,
int nBins,
double histMin,
double histMax) {
448 ip.setHistogramSize(nBins);
449 ip.setHistogramRange(histMin, histMax);
450 ImageStatistics stats = ImageStatistics.getStatistics(ip, mOptions,
getCalibration());
451 ip.setHistogramSize(256);
452 ip.setHistogramRange(0.0, 0.0);
467 int index = title.indexOf(
' ');
469 title = title.substring(0,index);
478 ImageCanvas ic = getCanvas();
480 double magnification = ic.getMagnification();
481 if (magnification!=1.0) {
482 double percent = magnification*100.0;
483 if (percent==(
int)percent)
484 scale =
" (" +
IJ.
d2s(percent,0) +
"%)";
486 scale =
" (" +
IJ.
d2s(percent,1) +
"%)";
492 public int getWidth() {
496 public int getHeight() {
515 case GRAY16: bitDepth=16;
break;
516 case GRAY32: bitDepth=32;
break;
522 protected void setType(
int type) {
525 int previousType = imageType;
527 if (imageType!=previousType) {
529 if (calibration!=null || globalCalibration!=null)
536 if (properties==null)
537 properties =
new Properties();
538 properties.put(key, value);
543 if (properties==null)
546 return properties.get(key);
569 return ip.isInvertedLut();
572 private int[] pvalue =
new int[4];
581 pvalue[0]=pvalue[1]=pvalue[2]=pvalue[3]=0;
588 index = ip.getPixel(x, y);
591 PixelGrabber pg =
new PixelGrabber(img,x,y,1,1,
false);
592 try {pg.grabPixels();}
593 catch (InterruptedException e){
return pvalue;};
594 pixels8 = (byte[])(pg.getPixels());
595 index = pixels8!=null?pixels8[0]&0xff:0;
604 int[] pixels32 =
new int[1];
605 ImageCanvas ic = getCanvas();
606 PixelGrabber pg =
new PixelGrabber(img, x, y, 1, 1, pixels32, 0, width);
607 try {pg.grabPixels();}
608 catch (InterruptedException e){
return pvalue;};
610 int r = (c&0xff0000)>>16;
611 int g = (c&0xff00)>>8;
618 if (ip!=null) pvalue[0] = ip.getPixel(x, y);
633 public Roi getRoi() {
643 Rectangle bounds = roi.getBounds();
644 if (bounds.width==0 && bounds.height==0)
651 this.roi.setImage(
this);
656 public void setRoi(
int x,
int y,
int width,
int height) {
657 setRoi(
new Rectangle(x, y, width, height));
665 roi =
new Roi(r.x, r.y, r.width, r.height);
678 switch (Toolbar.getToolId()) {
679 case Toolbar.RECTANGLE:
680 roi =
new Roi(x, y,
this);
683 roi =
new OvalRoi(x, y,
this);
685 case Toolbar.POLYGON:
686 case Toolbar.POLYLINE:
688 roi =
new PolygonRoi(x, y,
this);
690 case Toolbar.FREEROI:
691 case Toolbar.FREELINE:
692 roi =
new FreehandRoi(x, y,
this);
695 roi =
new Line(x, y,
this);
698 roi =
new TextRoi(x, y,
this);
719 Rectangle r = roi.getBounds();
720 if (r.width>0 && r.height>0) {
721 Roi.previousRoi = (Roi)roi.clone();
722 if (
IJ.debugMode)
IJ.
log(
"saveRoi: "+roi);
727 public void restoreRoi() {
728 if (Roi.previousRoi!=null) {
729 Roi pRoi = Roi.previousRoi;
730 Rectangle r = pRoi.getBounds();
731 if (r.width<=width || r.height<=height) {
732 roi = (Roi)pRoi.clone();
734 if ((r.x+r.width)>width || (r.y+r.height)>height)
735 roi.setLocation((width-r.width)/2, (height-r.height)/2);
746 if (fi!=null && fi.fileFormat!=FileInfo.UNKNOWN)
747 new FileOpener(fi).revertToSaved(
this);
748 else if (url!=null) {
749 IJ.showStatus(
"Loading: " + url);
750 Opener opener =
new Opener();
755 }
catch (Exception e) {}
757 Opener.convertGrayJpegTo8Bits(
this);
760 properties.remove(
"FHT");
761 if (
getTitle().startsWith(
"FFT of "))
776 FileInfo fi =
new FileInfo();
780 fi.intelByteOrder =
false;
782 fi.pixels = ip.getPixels();
785 fi.pixelWidth = cal.pixelWidth;
786 fi.pixelHeight = cal.pixelHeight;
787 fi.unit = cal.getUnit();
789 fi.frameInterval = cal.frameInterval;
790 if (cal.calibrated()) {
791 fi.calibrationFunction = cal.getFunction();
792 fi.coefficients = cal.getCoefficients();
793 fi.valueUnit = cal.getValueUnit();
799 fi.fileType = FileInfo.COLOR8;
801 fi.fileType = FileInfo.GRAY8;
802 fi.lutSize = lut.getMapSize();
803 fi.reds = lut.getReds();
804 fi.greens = lut.getGreens();
805 fi.blues = lut.getBlues();
808 fi.fileType = fi.GRAY16_UNSIGNED;
811 fi.fileType = fi.GRAY32_FLOAT;
814 fi.fileType = fi.RGB;
831 public boolean imageUpdate(Image img,
int flags,
int x,
int y,
int w,
int h) {
834 if ((flags & ERROR) != 0) {
835 errorLoadingImage =
true;
838 imageLoaded = (flags & (ALLBITS|FRAMEBITS|ABORT)) != 0;
846 if (locked || ignoreFlush)
861 this.ignoreFlush = ignoreFlush;
875 if (imp!=null && globalCalibration==null)
883 startTime = System.currentTimeMillis();
895 if (globalCalibration!=null)
896 return globalCalibration.copy();
898 if (calibration==null)
899 calibration =
new Calibration(
this);
910 calibration = cal.copy();
911 calibration.setImage(
this);
919 globalCalibration = null;
921 globalCalibration = global.copy();
933 private int savex, savey;
943 String getFFTLocation(
int x,
int y, Calibration cal) {
944 double center = width/2.0;
945 double r = Math.sqrt((x-center)*(x-center) + (y-center)*(y-center));
947 double theta = Math.atan2(y-center, x-center);
948 theta = theta*180.0/Math.PI;
949 if (theta<0) theta = 360.0+theta;
952 s +=
IJ.
d2s((width/r)*cal.pixelWidth,2) +
" " + cal.getUnit() +
"/c (" +
IJ.
d2s(r,0) +
")";
954 s +=
IJ.
d2s(width/r,2) +
" p/c (" +
IJ.
d2s(r,0) +
")";
955 s +=
", theta= " +
IJ.
d2s(theta,2) +
IJ.degreeSymbol;
963 return getFFTLocation(x, height-y-1, cal);
966 String s =
" x="+
IJ.
d2s(cal.getX(x)) +
", y=" +
IJ.
d2s(cal.getY(y));
969 String s =
" x="+x+
", y=" + y;
974 private String getValueAsString(
int x,
int y) {
979 double cValue = cal.getCValue(v[0]);
981 return(
", value=" + v[0]);
983 return(
", value=" +
IJ.
d2s(cValue) +
" ("+v[0]+
")");
985 return(
", value=" + Float.intBitsToFloat(v[0]));
987 return(
", index=" + v[3] +
", value=" + v[0] +
"," + v[1] +
"," + v[2]);
989 return(
", value=" + v[0] +
"," + v[1] +
"," + v[2]);
994 public String toString() {
995 return getTitle()+
" "+width+
"x"+height;
998 public ImageCanvas getCanvas() {
1002 public void setCanvas(ImageCanvas ic) {