| Resizer |

    package ij.plugin.filter;
    import ij.*;
    import ij.gui.*;
    import ij.process.*;
    import ij.measure.*;
    import ij.util.Tools;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;

    /** This plugin implements ImageJ's Resize command. */
    public class Resizer implements PlugInFilter, TextListener, ItemListener  {
        ImagePlus imp;
        private boolean crop;
        private static int newWidth;
        private static int newHeight;
        private static boolean constrain = true;
        private static boolean interpolate = true;
        private Vector fields, checkboxes;
        private double origWidth, origHeight;
        private boolean sizeToHeight;

        public int setup(String arg, ImagePlus imp) {
            crop = arg.equals("crop");
            this.imp = imp;
            IJ.register(Resizer.class);
            if (crop)
                return DOES_ALL+ROI_REQUIRED+NO_CHANGES;
            else
                return DOES_ALL+NO_CHANGES;
        }

        public void run(ImageProcessor ip) {
            Roi roi = imp.getRoi();
            if (roi!=null && roi.isLine()) {
                IJ.error("The Crop and Adjust->Size commands\ndo not work with line selections.");
                return;
            }
            Rectangle r = ip.getRoi();
            origWidth = r.width;;
            origHeight = r.height;
            sizeToHeight=false;
            boolean restoreRoi = crop && roi!=null && roi.getType()!=Roi.RECTANGLE;
            if (roi!=null && IJ.isJava2()) {
                Rectangle b = roi.getBounds();
                int w = ip.getWidth();
                int h = ip.getHeight();
                if (b.x<0 || b.y<0 || b.x+b.width>w || b.y+b.height>h) {
                    ShapeRoi shape1 = new ShapeRoi(roi);
                    ShapeRoi shape2 = new ShapeRoi(new Roi(0, 0, w, h));
                    roi = shape2.and(shape1);
                    if (restoreRoi) imp.setRoi(roi);
                }
            }
            if (crop) {
                Rectangle bounds = roi.getBounds();
                newWidth = bounds.width;
                newHeight = bounds.height;
                interpolate = false;
            } else {
                if (newWidth==0 || newHeight==0) {
                    newWidth = (int)origWidth/2;
                    newHeight = (int)origHeight/2;
                }
                if (constrain) newHeight = (int)(newWidth*(origHeight/origWidth));
                GenericDialog gd = new GenericDialog("Resize", IJ.getInstance());
                gd.addNumericField("Width (pixels):", newWidth, 0);
                gd.addNumericField("Height (pixels):", newHeight, 0);
                gd.addCheckbox("Constrain Aspect Ratio", constrain);
                gd.addCheckbox("Interpolate", interpolate);
                gd.addMessage("NOTE: Undo is not available");
                fields = gd.getNumericFields();
                for (int i=0; i<fields.size(); i++)
                    ((TextField)fields.elementAt(i)).addTextListener(this);
                checkboxes = gd.getCheckboxes();
                ((Checkbox)checkboxes.elementAt(0)).addItemListener(this);
                gd.showDialog();
                if (gd.wasCanceled())
                    return;
                newWidth = (int)gd.getNextNumber();
                newHeight = (int)gd.getNextNumber();
                if (gd.invalidNumber()) {
                    IJ.error("Width or height are invalid.");
                    return;
                }
                constrain = gd.getNextBoolean();
                interpolate = gd.getNextBoolean();
                if (constrain && newWidth==0)
                    sizeToHeight = true;
                if (newWidth<=0.0 && !constrain)  newWidth = 50;
                if (newHeight<=0.0) newHeight = 50;
            }

            if (!crop && constrain) {
                if (sizeToHeight)
                    newWidth = (int)(newHeight*(origWidth/origHeight));
                else
                    newHeight = (int)(newWidth*(origHeight/origWidth));
            }
            if (ip.getWidth()==1 || ip.getHeight()==1)
                ip.setInterpolate(false);
            else
                ip.setInterpolate(interpolate);

            int nSlices = imp.getStackSize();
            try {
                StackProcessor sp = new StackProcessor(imp.getStack(), ip);
                ImageStack s2 = sp.resize(newWidth, newHeight);
                int newSize = s2.getSize();
                if (s2.getWidth()>0 && newSize>0) {
                    if (restoreRoi)
                        imp.killRoi();
                    //imp.hide();
                    Calibration cal = imp.getCalibration();
                    if (cal.scaled()) {
                        cal.pixelWidth *= origWidth/newWidth;
                        cal.pixelHeight *= origHeight/newHeight;
                        imp.setCalibration(cal);
                    }
                    imp.setStack(null, s2);
                    //imp.show();
                    if (restoreRoi) {
                        imp.restoreRoi();
                        roi = imp.getRoi();
                        if (roi!=null) {
                            roi.setLocation(0, 0);
                            imp.draw();
                        }
                    }
                }
                if (nSlices>1 && newSize<nSlices)
                    IJ.error("ImageJ ran out of memory causing \nthe last "+(nSlices-newSize)+" slices to be lost.");
            } catch(OutOfMemoryError o) {
                IJ.outOfMemory("Resize");
            }
        }

        public void textValueChanged(TextEvent e) {
            TextField widthField = (TextField)fields.elementAt(0);
            TextField heightField = (TextField)fields.elementAt(1);
            int width = (int)Tools.parseDouble(widthField.getText(),-99);
            int height = (int)Tools.parseDouble(heightField.getText(),-99);
            if (width==-99 || height==-99)
                return;
            if (constrain) {
                if (width!=newWidth) {
                    sizeToHeight = false;
                    newWidth = width;
                    updateFields();
                } else if (height!=newHeight) {
                    sizeToHeight = true;
                    newHeight = height;
                    updateFields();
                }
            }
        }

        void updateFields() {
            if (sizeToHeight) {
                newWidth = (int)(newHeight*(origWidth/origHeight));
                TextField widthField = (TextField)fields.elementAt(0);
                widthField.setText(""+newWidth);
            } else {
                newHeight = (int)(newWidth*(origHeight/origWidth));
                TextField heightField = (TextField)fields.elementAt(1);
                heightField.setText(""+newHeight);
            }
       }

        public void itemStateChanged(ItemEvent e) {
            Checkbox cb = (Checkbox)checkboxes.elementAt(0);
            boolean newConstrain = cb.getState();
            if (newConstrain && newConstrain!=constrain)
                updateFields();
            constrain = newConstrain;
        }

    }

| Resizer |