diff --git a/src/main/java/plugins/tprovoost/scale/Scale.java b/src/main/java/plugins/tprovoost/scale/Scale.java index af5f315e38bb02b0c8311a2d50de3a06eea6d881..db03aab9cd913f63ce8907eefbe2a2f96b07c0ec 100644 --- a/src/main/java/plugins/tprovoost/scale/Scale.java +++ b/src/main/java/plugins/tprovoost/scale/Scale.java @@ -1,56 +1,101 @@ package plugins.tprovoost.scale; import icy.gui.main.GlobalSequenceListener; +import icy.gui.viewer.Viewer; import icy.main.Icy; +import icy.painter.Overlay; import icy.plugin.abstract_.Plugin; import icy.plugin.interface_.PluginDaemon; +import icy.preferences.XMLPreferences; import icy.sequence.Sequence; +import icy.system.IcyHandledException; -public class Scale extends Plugin implements PluginDaemon +/** + * Scale bar plug-in for Icy. Displays a scale bar on 2D viewers, with various display adjustment + * options, such as: + * <ul> + * <li>Color</li> + * <li>Size and unit (manually or automatically)</li> + * <li>Position (each image corner)</li> + * <li>Hide/Show text</li> + * </ul> + * These options can be managed from the graphical interface (in the "Layers" section of the + * inspector), or within scripts (see {@link #addScaleBarTo(Sequence)} and + * {@link #removeScaleBarFrom(Sequence)} + * + * @author Thomas Provoost, Stephane Dallongeville, Alexandre Dufour + */ +public class Scale extends Plugin implements PluginDaemon, GlobalSequenceListener { - ScalePainter sp; - GlobalSequenceListener globalSequenceListener; + private static XMLPreferences preferences = null; + + @Override + public void init() + { + if (preferences == null) + preferences = getPreferencesRoot(); + + Icy.getMainInterface().addGlobalSequenceListener(this); + } @Override public void run() { - // nothing to do here + for (Sequence s : getSequences()) + addScaleBarTo(s); } @Override public void stop() { - for (Sequence sequence : Icy.getMainInterface().getSequences()) - sequence.removeOverlay(sp); + for (Sequence s : getSequences()) + removeScaleBarFrom(s); - Icy.getMainInterface().removeGlobalSequenceListener(globalSequenceListener); + Icy.getMainInterface().removeGlobalSequenceListener(this); } @Override - public void init() + public void sequenceOpened(Sequence sequence) + { + addScaleBarTo(sequence); + } + + @Override + public void sequenceClosed(Sequence sequence) { - // create painter - sp = new ScalePainter(); - globalSequenceListener = new GlobalSequenceListener() + removeScaleBarFrom(sequence); + } + + public static ScaleBarOverlay addScaleBarTo(Sequence sequence) + { + if (sequence == null) + throw new IcyHandledException("Cannot add the scale bar: no sequence specified"); + + if (sequence.hasOverlay(ScaleBarOverlay.class)) + return sequence.getOverlays(ScaleBarOverlay.class).get(0); + + ScaleBarOverlay overlay = new ScaleBarOverlay(preferences); + + sequence.addOverlay(overlay); + + // Try to detect if the sequence is a screenshot (via its name) + // => hide the overlay by default (but don't remove it) + String name = sequence.getName().toLowerCase(); + if (name.startsWith("rendering") || name.startsWith("screen shot")) { - @Override - public void sequenceOpened(Sequence sequence) - { - sequence.addOverlay(sp); - } - - @Override - public void sequenceClosed(Sequence sequence) - { - sequence.removeOverlay(sp); - } - }; - - // add the Scale Bar overlay on opened sequences - for (Sequence sequence : Icy.getMainInterface().getSequences()) - sequence.addOverlay(sp); - - // listen new opened sequence - Icy.getMainInterface().addGlobalSequenceListener(globalSequenceListener); + for (Viewer viewer : sequence.getViewers()) + viewer.getCanvas().getLayer(overlay).setVisible(false); + } + + return overlay; + } + + public static void removeScaleBarFrom(Sequence sequence) + { + if (sequence == null) + throw new IcyHandledException("Cannot remove the scale bar: no sequence specified"); + + for (Overlay o : sequence.getOverlays(ScaleBarOverlay.class)) + sequence.removeOverlay(o); } } diff --git a/src/main/java/plugins/tprovoost/scale/ScaleBarLocation.java b/src/main/java/plugins/tprovoost/scale/ScaleBarLocation.java new file mode 100644 index 0000000000000000000000000000000000000000..98cf88223707df0615bdb506456dba37a2ffa3d5 --- /dev/null +++ b/src/main/java/plugins/tprovoost/scale/ScaleBarLocation.java @@ -0,0 +1,34 @@ +package plugins.tprovoost.scale; + +public enum ScaleBarLocation +{ + IMAGE_BOTTOM_LEFT("Bottom left of image"), VIEWER_BOTTOM_LEFT("Bottom left of viewer"), + IMAGE_BOTTOM_RIGHT("Bottom right of image"), VIEWER_BOTTOM_RIGHT("Bottom right of viewer"), + IMAGE_TOP_LEFT("Top left of image"), VIEWER_TOP_LEFT("Top left of viewer"), IMAGE_TOP_RIGHT("Top right of image"), + VIEWER_TOP_RIGHT("Top right of viewer"); + + public final String name; + + private ScaleBarLocation(String name) + { + this.name = name; + } + + public String toString() + { + return name; + } + + public boolean isRelativeToViewer() + { + return this == VIEWER_BOTTOM_LEFT || this == VIEWER_BOTTOM_RIGHT || this == VIEWER_TOP_LEFT + || this == VIEWER_TOP_RIGHT; + } + + public boolean isRelativeToImage() + { + return this == IMAGE_BOTTOM_LEFT || this == IMAGE_BOTTOM_RIGHT || this == IMAGE_TOP_LEFT + || this == IMAGE_TOP_RIGHT; + } + +} diff --git a/src/main/java/plugins/tprovoost/scale/ScaleBarOverlay.java b/src/main/java/plugins/tprovoost/scale/ScaleBarOverlay.java new file mode 100644 index 0000000000000000000000000000000000000000..ef564e474800a552f14e09d6dbb579a57e035c7c --- /dev/null +++ b/src/main/java/plugins/tprovoost/scale/ScaleBarOverlay.java @@ -0,0 +1,502 @@ +package plugins.tprovoost.scale; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.RenderingHints; +import java.awt.geom.Line2D; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import icy.canvas.IcyCanvas; +import icy.canvas.IcyCanvas2D; +import icy.math.MathUtil; +import icy.math.UnitUtil; +import icy.math.UnitUtil.UnitPrefix; +import icy.painter.Overlay; +import icy.preferences.XMLPreferences; +import icy.sequence.Sequence; +import icy.system.thread.ThreadUtil; +import icy.util.ColorUtil; +import icy.util.GraphicsUtil; +import plugins.adufour.vars.gui.model.IntegerRangeModel; +import plugins.adufour.vars.gui.swing.SwingVarEditor; +import plugins.adufour.vars.lang.Var; +import plugins.adufour.vars.lang.VarBoolean; +import plugins.adufour.vars.lang.VarColor; +import plugins.adufour.vars.lang.VarEnum; +import plugins.adufour.vars.lang.VarInteger; +import plugins.kernel.canvas.VtkCanvas; + +/** + * Scale Bar Overay class + * + * @author Stephane + */ +public class ScaleBarOverlay extends Overlay +{ + private static final double[] scaleRoundedFactors = {1.0D, 2.0D, 3.0D, 4.0D, 5.0D, 6.0D, 7.0D, 8.0D, 9.0D, 10.0D, + 20.0D, 30.0D, 40.0D, 50.0D, 60.0D, 70.0D, 80.0D, 90.0D, 100.0D, 200.0D, 300.0D, 400.0D, 500.0D, 600.0D, + 700.0D, 800.0D, 900.0D}; + + private final XMLPreferences preferences; + private final Line2D.Double line; + private JPanel optionPanel; + private boolean init = false; + + // settings + private final VarEnum<ScaleBarLocation> location; + private final VarColor color; + private final VarBoolean showText; + private final VarInteger size; + private final VarInteger thickness; + private final VarEnum<ScaleBarUnit> unit; + private final VarBoolean autoSize; + + public ScaleBarOverlay(XMLPreferences preferences) + { + super("Scale bar", OverlayPriority.TOPMOST); + + this.preferences = preferences; + line = new Line2D.Double(); + + // scale bar location + location = new VarEnum<ScaleBarLocation>("Location", + ScaleBarLocation.valueOf(preferences.get("location", ScaleBarLocation.VIEWER_BOTTOM_LEFT.name()))) + { + @Override + public void setValue(ScaleBarLocation newValue) + { + if (getValue().equals(newValue)) + return; + + super.setValue(newValue); + + preferences.put("location", newValue.name()); + + painterChanged(); + } + }; + + // scale bar color + color = new VarColor("Color", new Color(preferences.getInt("color", new Color(255, 255, 255, 255).getRGB()))) + { + @Override + public void setValue(Color newValue) + { + if (getValue().equals(newValue)) + return; + + super.setValue(newValue); + + preferences.putInt("color", newValue.getRGB()); + + painterChanged(); + } + }; + + // Display text over the scale bar + showText = new VarBoolean("Display size", preferences.getBoolean("showText", true)) + { + @Override + public void setValue(Boolean newValue) + { + if (getValue().equals(newValue)) + return; + + super.setValue(newValue); + + preferences.putBoolean("showText", newValue); + + painterChanged(); + } + }; + + // Scale bar size (default: 10 units) + size = new VarInteger("Size", preferences.getInt("size", 10)) + { + @Override + public void setValue(Integer newValue) + { + if (getValue().equals(newValue)) + return; + + super.setValue(newValue); + + preferences.putInt("size", newValue); + + painterChanged(); + } + }; + + // Scale bar thickness (default: 5) + thickness = new VarInteger("Thickness", preferences.getInt("thickness", 5)) + { + @Override + public void setValue(Integer newValue) + { + if (getValue().equals(newValue)) + return; + + super.setValue(newValue); + + preferences.putInt("thickness", newValue); + + painterChanged(); + } + }; + + // Scale bar unit (default: microns) + unit = new VarEnum<ScaleBarUnit>("Unit", + ScaleBarUnit.valueOf(preferences.get("unit", ScaleBarUnit.MICRO.name()))) + { + @Override + public void setValue(ScaleBarUnit newValue) + { + if (getValue().equals(newValue)) + return; + + super.setValue(newValue); + + preferences.put("unit", newValue.name()); + + painterChanged(); + } + }; + + // auto-adjust the size and unit of the scale bar + autoSize = new VarBoolean("Auto-adjust size", preferences.getBoolean("autoSize", false)) + { + @Override + public void setValue(Boolean newValue) + { + if (getValue().equals(newValue)) + return; + + super.setValue(newValue); + + preferences.putBoolean("autoSize", newValue); + + painterChanged(); + + } + }; + + Integer currentSize = size.getValue(); + size.setDefaultEditorModel(new IntegerRangeModel(10, 1, 999, 1)); + size.setValue(currentSize); + + Integer currentThickness = thickness.getValue(); + thickness.setDefaultEditorModel(new IntegerRangeModel(5, 1, 20, 1)); + thickness.setValue(currentThickness); + + // do graphical stuff to the graphical thread + ThreadUtil.invokeLater(new Runnable() + { + @Override + public void run() + { + initOptionPanel(); + } + }); + } + + /** + * Scale bar color (default: white) + */ + + private void initOptionPanel() + { + optionPanel = new JPanel(new GridBagLayout()); + + for (Var<?> variable : new Var<?>[] {location, color, autoSize, size, thickness, showText}) + { + GridBagConstraints gbc = new GridBagConstraints(); + + gbc.insets = new Insets(2, 10, 2, 5); + gbc.fill = GridBagConstraints.BOTH; + optionPanel.add(new JLabel(variable.getName()), gbc); + + // special case: show unit next to size + if (variable == size) + { + gbc.weightx = 0.5; + + SwingVarEditor<?> editor = (SwingVarEditor<?>) variable.createVarEditor(true); + optionPanel.add(editor.getEditorComponent(), gbc); + + gbc.gridwidth = GridBagConstraints.REMAINDER; + + SwingVarEditor<?> unitEditor = (SwingVarEditor<?>) unit.createVarEditor(true); + optionPanel.add(unitEditor.getEditorComponent(), gbc); + } + else + { + gbc.weightx = 1; + gbc.gridwidth = GridBagConstraints.REMAINDER; + SwingVarEditor<?> editor = (SwingVarEditor<?>) variable.createVarEditor(true); + optionPanel.add(editor.getEditorComponent(), gbc); + } + } + } + + @Override + public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas) + { + if (canvas instanceof VtkCanvas && !init) + { + init = true; + + // VtkCanvas vtk = (VtkCanvas) canvas; + + // vtkScalarBarActor sb = new vtkScalarBarActor(); + + // vtk.getRenderer().AddActor(sb); + + return; + } + else if (g == null || !(canvas instanceof IcyCanvas2D)) + return; + + final IcyCanvas2D c2 = (IcyCanvas2D) canvas; + final Graphics2D g2 = (Graphics2D) g.create(); + + if (autoSize.getValue()) + { + int sizeW = Math.min(c2.getCanvasSizeX() / 4, Math.max(c2.getCanvasSizeX() / 7, 120)); + // sequence.getSizeX() / 7; + + // don't draw a scale bar larger than the image itself + if (location.getValue().isRelativeToImage()) + // sizeW = Math.min(c2.getCanvasSizeX() / 4, Math.max(c2.getCanvasSizeX() / 7, 120)); + sizeW = (int) Math.min(sizeW, sequence.getSizeX() * canvas.getScaleX() * 0.5); + + double valueReal = (sizeW * sequence.getPixelSizeX() / canvas.getScaleX()); + UnitPrefix bestUnit = UnitUtil.getBestUnit(valueReal * 0.1, UnitUtil.UnitPrefix.MICRO, 1); + double valueRealBestUnit = UnitUtil.getValueInUnit(valueReal, UnitPrefix.MICRO, bestUnit); + + double closestScale = MathUtil.closest(valueRealBestUnit, scaleRoundedFactors); + size.setValue((int) closestScale); + unit.setValue(ScaleBarUnit.getUnitFrom(bestUnit)); + } + + String text = size.getValue() + " " + unit.getValue(); + + double length = UnitUtil.getValueInUnit(size.getValue(), unit.getValue().asUnitPrefix(), UnitPrefix.MICRO) + / sequence.getPixelSizeX(); + + int textYfactor = 0; + float finalThickness = this.thickness.getValue().floatValue(); + + switch (location.getValue()) + { + case VIEWER_BOTTOM_LEFT: + g2.transform(c2.getInverseTransform()); + line.x1 = canvas.getCanvasSizeX() * 0.05; + line.x2 = line.x1 + length * c2.getScaleX(); + line.y1 = line.y2 = canvas.getCanvasSizeY() * 0.95; + textYfactor = -2; + break; + + case IMAGE_BOTTOM_LEFT: + line.x1 = sequence.getSizeX() * 0.05; + line.x2 = line.x1 + length; + line.y1 = line.y2 = sequence.getSizeY() * 0.95; + textYfactor = -2; + finalThickness = (float) c2.canvasToImageLogDeltaX((int) finalThickness); + break; + + case VIEWER_BOTTOM_RIGHT: + g2.transform(c2.getInverseTransform()); + line.x1 = canvas.getCanvasSizeX() * 0.95; + line.x2 = line.x1 - length * c2.getScaleX(); + line.y1 = line.y2 = canvas.getCanvasSizeY() * 0.95; + textYfactor = -2; + break; + + case IMAGE_BOTTOM_RIGHT: + line.x1 = sequence.getSizeX() * 0.95; + line.x2 = line.x1 - length; + line.y1 = line.y2 = sequence.getSizeY() * 0.95; + textYfactor = -2; + finalThickness = (float) c2.canvasToImageLogDeltaX((int) finalThickness); + break; + + case VIEWER_TOP_LEFT: + g2.transform(c2.getInverseTransform()); + line.x1 = canvas.getCanvasSizeX() * 0.05; + line.x2 = line.x1 + length * c2.getScaleX(); + line.y1 = line.y2 = canvas.getCanvasSizeY() * 0.05; + textYfactor = 4; + break; + + case IMAGE_TOP_LEFT: + line.x1 = sequence.getSizeX() * 0.05; + line.x2 = line.x1 + length; + line.y1 = line.y2 = sequence.getSizeY() * 0.05; + textYfactor = 4; + finalThickness = (float) c2.canvasToImageLogDeltaX((int) finalThickness); + break; + + case VIEWER_TOP_RIGHT: + g2.transform(c2.getInverseTransform()); + line.x1 = canvas.getCanvasSizeX() * 0.95; + line.x2 = line.x1 - length * c2.getScaleX(); + line.y1 = line.y2 = canvas.getCanvasSizeY() * 0.05; + textYfactor = 4; + break; + + case IMAGE_TOP_RIGHT: + line.x1 = sequence.getSizeX() * 0.95; + line.x2 = line.x1 - length; + line.y1 = line.y2 = sequence.getSizeY() * 0.05; + textYfactor = 4; + finalThickness = (float) c2.canvasToImageLogDeltaX((int) finalThickness); + break; + } + + // draw scale bar line + g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2.setStroke(new BasicStroke(finalThickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); + if (ColorUtil.getLuminance(color.getValue()) > 128) + g2.setColor(Color.darkGray); + else + g2.setColor(Color.lightGray); + line.x1 += 1; + line.y1 += 1; + line.x2 += 1; + line.y2 += 1; + g2.draw(line); + line.x1 -= 1; + line.y1 -= 1; + line.x2 -= 1; + line.y2 -= 1; + g2.setColor(color.getValue()); + g2.draw(line); + + // draw text + if (showText.getValue()) + { + g2.setFont(g2.getFont().deriveFont(Font.BOLD, finalThickness * 3)); + GraphicsUtil.drawHCenteredString(g2, text, (int) line.getBounds().getCenterX(), + (int) (line.getBounds().getCenterY() + (finalThickness * textYfactor * 3)), true); + } + + g2.dispose(); + } + + @Override + public JPanel getOptionsPanel() + { + return optionPanel; + } + + /** + * @return <code>true</code> if the scale bar automatically adjusts its size and unit + */ + public boolean getAutoSize() + { + return autoSize.getValue(); + } + + /** + * @return the color of the scale bar + */ + public Color getColor() + { + return color.getValue(); + } + + /** + * @return the location of the scale bar on the image + */ + public ScaleBarLocation getLocation() + { + return location.getValue(); + } + + /** + * @return the scale bar size (in metric units as defined by the pixel size) + */ + public double getSize() + { + return size.getValue(); + } + + /** + * @return whether the scale bar's size is currently displayed next to it + */ + public boolean getTextDisplay() + { + return showText.getValue(); + } + + /** + * Sets whether the scale should automatically guess its optimal size and unit + * + * @param autoSize + */ + public void setAutoSize(boolean autoSize) + { + this.autoSize.setValue(autoSize); + } + + /** + * Sets the color of the scale bar + * + * @param color + * the new color of the scale bar + */ + public void setColor(Color color) + { + this.color.setValue(color); + } + + /** + * Sets the location of the scale bar + * + * @param location + * the new location of the scale bar + */ + public void setLocation(ScaleBarLocation location) + { + this.location.setValue(location); + } + + /** + * Sets whether the scale bar's size should appear next to it + * + * @param displayText + */ + public void setTextDisplay(boolean displayText) + { + this.showText.setValue(displayText); + } + + /** + * Sets the size of the scale bar in metric units, as defined by the pixel size + * + * @param size + * the new size of the scale bar + */ + public void setSize(int size) + { + this.size.setValue(size); + } + + /** + * Sets the scale bar unit + * + * @param unit + * the new unit + */ + public void setUnit(UnitPrefix unit) + { + this.unit.setValue(ScaleBarUnit.getUnitFrom(unit)); + } +} \ No newline at end of file diff --git a/src/main/java/plugins/tprovoost/scale/ScaleBarUnit.java b/src/main/java/plugins/tprovoost/scale/ScaleBarUnit.java new file mode 100644 index 0000000000000000000000000000000000000000..7d5522fd60a9c72952b4cf10956f6a8c63145289 --- /dev/null +++ b/src/main/java/plugins/tprovoost/scale/ScaleBarUnit.java @@ -0,0 +1,67 @@ +package plugins.tprovoost.scale; + +import icy.math.UnitUtil; +import icy.math.UnitUtil.UnitPrefix; + +public enum ScaleBarUnit +{ + KILO, NONE, MILLI, MICRO, NANO; + + @Override + public String toString() + { + switch (this) + { + case KILO: + return "km"; + case NONE: + return "m"; + case MILLI: + return "mm"; + default: + case MICRO: + return UnitUtil.MICRO_STRING + "m"; + case NANO: + return "nm"; + } + } + + public UnitPrefix asUnitPrefix() + { + switch (this) + { + case KILO: + return UnitPrefix.KILO; + case NONE: + return UnitPrefix.NONE; + case MILLI: + return UnitPrefix.MILLI; + default: + case MICRO: + return UnitPrefix.MICRO; + case NANO: + return UnitPrefix.NANO; + } + } + + public static ScaleBarUnit getUnitFrom(UnitPrefix up) + { + switch (up) + { + case GIGA: + case MEGA: + case KILO: + return KILO; + case NONE: + return NONE; + case MILLI: + return MILLI; + case MICRO: + default: + return MICRO; + case NANO: + case PICO: + return NANO; + } + } +} diff --git a/src/main/java/plugins/tprovoost/scale/ScalePainter.java b/src/main/java/plugins/tprovoost/scale/ScalePainter.java deleted file mode 100644 index af4f9ce1b0e19fd317131b0a09148e3a9d765b2e..0000000000000000000000000000000000000000 --- a/src/main/java/plugins/tprovoost/scale/ScalePainter.java +++ /dev/null @@ -1,159 +0,0 @@ -package plugins.tprovoost.scale; - -import icy.canvas.IcyCanvas; -import icy.canvas.IcyCanvas2D; -import icy.math.MathUtil; -import icy.math.UnitUtil; -import icy.math.UnitUtil.UnitPrefix; -import icy.painter.Overlay; -import icy.sequence.Sequence; -import icy.util.GraphicsUtil; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Shape; -import java.awt.Stroke; - -public class ScalePainter extends Overlay -{ - /** - * Possible rounded scale factors : 1 --> 900 - */ - final static double[] scaleRoundedFactors = new double[] {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d, 10d, 20d, 30d, 40d, - 50d, 60d, 70d, 80d, 90d, 100d, 200d, 300d, 400d, 500d, 600d, 700d, 800d, 900d}; - - public ScalePainter() - { - super("Scale Bar"); - } - - @Override - public void paint(Graphics2D g2, Sequence sequence, IcyCanvas canvas) - { - if (g2 == null) - return; - if (!(canvas instanceof IcyCanvas2D)) - return; - - final IcyCanvas2D c2d = (IcyCanvas2D) canvas; - final Graphics2D g = (Graphics2D) g2.create(); - - double scaleFactor = c2d.getScaleX(); - g.transform(c2d.getInverseTransform()); - - BasicStroke[] stroke = new BasicStroke[4]; - stroke[0] = new BasicStroke(2f); - stroke[1] = new BasicStroke(3f); - stroke[2] = new BasicStroke(4f); - stroke[3] = new BasicStroke(5f); - int w = canvas.getCanvasSizeX(); - int h = canvas.getCanvasSizeY(); - double pxSize = sequence.getPixelSizeX(); - int space = 20; // spacing from borders - - int sizeW = w / 8; - // get the value with the best display possible - double valueReal = sizeW * pxSize / scaleFactor / 10; - UnitPrefix bestUnit = UnitUtil.getBestUnit(valueReal, UnitPrefix.MICRO, 1); - double valueRealBestUnit = UnitUtil.getValueInUnit(valueReal * 10, UnitPrefix.MICRO, bestUnit); - - double closestScale = MathUtil.closest(valueRealBestUnit, scaleRoundedFactors); - - // closest scale in px - int closestScPx = (int) (UnitUtil.getValueInUnit(closestScale, bestUnit, UnitPrefix.MICRO) / pxSize * scaleFactor); - // int closestScPx = closestScale; - - g.setColor(Color.BLACK); - g.setStroke(stroke[3]); - // g.drawLine(w - space - closestScPx, h - space, w - space, h - space); - g.drawLine(space, h - space, space + closestScPx, h - space); - - g.setColor(Color.WHITE); - g.setStroke(stroke[2]); - g.drawLine(space, h - space, space + closestScPx, h - space); - - int fontSize = 14; - Font font = new Font("Arial", Font.PLAIN, fontSize); - g.setFont(font); - String pixelString = "" + closestScale + " " + bestUnit + "m"; - int txW = g.getFontMetrics().charsWidth(pixelString.toCharArray(), 0, pixelString.length()); - int txH = g.getFontMetrics().getHeight(); - - g.setColor(Color.black); - // GraphicsUtil.drawString(g, pixelString, w - space - closestScPx / 2 - - // txW / 2, h - space - txH, true); - GraphicsUtil.drawString(g, pixelString, space + closestScPx / 2 - txW / 2, h - space - txH, true); - - g.dispose(); - } - - double convertScale(IcyCanvas canvas, double value) - { - return canvas.canvasToImageLogDeltaX((int) value); - } - - public class CompositeStroke implements Stroke - { - private Stroke stroke1, stroke2; - - public CompositeStroke(Stroke stroke1, Stroke stroke2) - { - this.stroke1 = stroke1; - this.stroke2 = stroke2; - } - - @Override - public Shape createStrokedShape(Shape shape) - { - return stroke2.createStrokedShape(stroke1.createStrokedShape(shape)); - } - } - -// private int findBestScale(IcyCanvas2D canvas, Sequence s) -// { -// int w = s.getWidth(); -// int minSize = w / 8; -// int maxSize = w / 4; -// double pxSize = s.getPixelSizeX(); -// double tab[] = new double[maxSize - minSize]; -// double scaleFactor = canvas.getScaleX(); -// -// // generate all values -// for (int i = minSize; i < maxSize; ++i) -// { -// -// // get the value with the best display possible -// double valueReal = i * pxSize / scaleFactor; -// UnitPrefix bestUnit = UnitUtil.getBestUnit(valueReal, UnitPrefix.MICRO, 1); -// double bestValue = UnitUtil.getValueInUnit(valueReal, UnitPrefix.MICRO, bestUnit); -// bestValue = ((int) (bestValue * 100)) / 100d; -// -// tab[i - minSize] = bestValue; -// } -// -// // return the first value with a round value -// for (int i = 0; i < maxSize - minSize; ++i) -// { -// double bestValue = tab[i]; -// if (bestValue == (int) bestValue) -// { -// return i + minSize; -// } -// } -// -// // otherwise, return first value with only one decimal -// for (int i = 0; i < maxSize - minSize; ++i) -// { -// double bestValue = tab[i]; -// if (bestValue == ((int) (bestValue * 10)) / 10d) -// { -// return i + minSize; -// } -// } -// -// // otherwise, return w / 4 -// return w / 4; -// } -} diff --git a/src/main/java/plugins/tprovoost/scale/ScalePainterOld.java b/src/main/java/plugins/tprovoost/scale/ScalePainterOld.java deleted file mode 100644 index caf0c37945f25f8037de04c34b7d146ec29fdd2a..0000000000000000000000000000000000000000 --- a/src/main/java/plugins/tprovoost/scale/ScalePainterOld.java +++ /dev/null @@ -1,105 +0,0 @@ -package plugins.tprovoost.scale; - -import icy.canvas.IcyCanvas; -import icy.canvas.IcyCanvas2D; -import icy.math.UnitUtil; -import icy.math.UnitUtil.UnitPrefix; -import icy.painter.Overlay; -import icy.roi.ROI2D; -import icy.sequence.Sequence; -import icy.util.GraphicsUtil; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Shape; -import java.awt.Stroke; - -public class ScalePainterOld extends Overlay -{ - public ScalePainterOld() - { - super("Scale Bar"); - } - - @Override - public void paint(Graphics2D g2, Sequence sequence, IcyCanvas canvas) - { - if (g2 == null) - return; - Graphics2D g = (Graphics2D) g2.create(); - // g.transform(((IcyCanvas2D) canvas).getInverseTransform()); - int w = sequence.getWidth(); - int h = sequence.getHeight(); - int sizeW = w / 10; - double pxSize = sequence.getPixelSizeX(); - int spaceFBords = 20; // spacing from borders - - BasicStroke[] stroke = new BasicStroke[4]; - stroke[0] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(2)); - stroke[1] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(3)); - stroke[2] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(4)); - stroke[3] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(5)); - - // get the value with the best display possible - double valueReal = sizeW * pxSize / 10; - UnitPrefix bestUnit = UnitUtil.getBestUnit(valueReal, UnitPrefix.MICRO, 1); - double bestValue = UnitUtil.getValueInUnit(valueReal * 10, UnitPrefix.MICRO, bestUnit); - - // get the best scale possible - int closestScale = 0; - if (bestValue < 10) - { - closestScale = (int) bestValue; - } else - closestScale = (int) (bestValue / 10) * 10; - - // closest scale in px - int closestScPx = (int) (UnitUtil.getValueInUnit(closestScale, bestUnit, UnitPrefix.MICRO) / pxSize); - - g.setColor(Color.BLACK); - g.setStroke(stroke[3]); - g.drawLine(w - spaceFBords - closestScPx, h - spaceFBords, w - spaceFBords, h - spaceFBords); - - g.setColor(Color.WHITE); - g.setStroke(stroke[2]); - g.drawLine(w - spaceFBords - closestScPx, h - spaceFBords, w - spaceFBords, h - spaceFBords); - - int fontSize = (int) canvas.canvasToImageLogDeltaX(14); - Font font = new Font("Arial", Font.PLAIN, fontSize); - g.setFont(font); - String pixelString = "" + closestScale + " " + bestUnit + "m"; - int txW = g.getFontMetrics().charsWidth(pixelString.toCharArray(), 0, pixelString.length()); - int txH = g.getFontMetrics().getHeight(); - - // g.fillRect(w - spaceFBords - closestScPx / 2 - txW / 2, h - - // spaceFBords - txH, txW, txH); - - g.setColor(Color.black); - GraphicsUtil.drawString(g, pixelString, w - spaceFBords - closestScPx / 2 - txW / 2, h - spaceFBords - txH, true); - - g.dispose(); - } - - double convertScale(IcyCanvas canvas, double value) - { - return canvas.canvasToImageLogDeltaX((int) value); - } - - public class CompositeStroke implements Stroke - { - private Stroke stroke1, stroke2; - - public CompositeStroke(Stroke stroke1, Stroke stroke2) - { - this.stroke1 = stroke1; - this.stroke2 = stroke2; - } - - public Shape createStrokedShape(Shape shape) - { - return stroke2.createStrokedShape(stroke1.createStrokedShape(shape)); - } - } -}