/** * Copyright (C) 2008-2011 Daniel Senff * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package de.danielsenff.imageflow.models.unit; import ij.ImagePlus; import ij.WindowManager; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.util.ArrayList; import java.util.Vector; import de.danielsenff.imageflow.gui.UnitPropertiesDialog; import de.danielsenff.imageflow.models.MacroElement; import de.danielsenff.imageflow.models.connection.Output; import de.danielsenff.imageflow.models.datatype.ImageDataType; import de.danielsenff.imageflow.models.parameter.ChoiceParameter; import de.danielsenff.imageflow.models.parameter.Parameter; import de.danielsenff.imageflow.utils.ImageJHelper; /** * Specialized {@link UnitElement} for loading image files. * This supports the file formats ImageJ does natively. * @author danielsenff * */ public class ImportUnitElement extends UnitElement implements ImageSourceUnit { private static final int WINDOW_PARAMETER_INDEX = 0; private ImagePlus image; /** * @param origin * @param unitName * @param macroElement */ public ImportUnitElement(final Point origin, final String unitName, final MacroElement macroElement) { super(origin, unitName, macroElement); } /** * @param origin * @param unitName * @param macroString */ public ImportUnitElement(final Point origin, final String unitName, final String macroString) { super(origin, unitName, macroString); } /** * @param origin * @param unitName * @param macroElement * @param filepath */ public ImportUnitElement(final Point origin, final String unitName, final MacroElement macroElement, final String filepath) { super(origin, unitName, macroElement); } /** * @param origin * @param unitName * @param macroString * @param filepath */ public ImportUnitElement(final Point origin, final String unitName, final String macroString, final String filepath) { super(origin, unitName, macroString); } @Override public ImportUnitElement clone() { // clone the object String imageJSyntax; try { imageJSyntax = (String) cloneNonClonableObject(this.obj); } catch (CloneNotSupportedException e) { imageJSyntax = ((MacroElement)this.obj).getImageJSyntax(); } ImportUnitElement clone = new ImportUnitElement(new Point(origin.x+15, origin.y+15), this.label, imageJSyntax); for (int j = 0; j < getInputsCount(); j++) { cloneInput(clone, j); } for (int i = 0; i < getOutputsCount(); i++) { cloneOutput(clone, i); } for (Parameter parameter : parameters) { cloneParameter(clone, parameter); } clone.setOriginalUnit(this); clone.setDisplay(isDisplay()); clone.setDisplaySilent(isDisplaySilent()); clone.setColor(this.color); clone.setIcon(this.preview); clone.setHelpString(this.infoText); clone.setCompontentSize(this.getCompontentSize()); return clone; } class ImportUnitPropertiesDialog extends UnitPropertiesDialog { public ImportUnitPropertiesDialog(UnitElement unit, Point point) { super(unit, point); } @Override protected void addParameterWidgets(final UnitElement unit) { if (unit.getParameters().isEmpty()) { addMessage("This unit has no parameters and can not be adjusted."); } else { ChoiceParameter windowChoice = getWindowChoiceParameter(unit.getParameters()); if(WindowManager.getCurrentImage() != null) { Vector<String> imageWindows = getImageWindows(); // if(imageWindows.contains(windowChoice.getValue())) { // // if same window is opened as before // gd.addMessage("Expected opened Image by the name "+windowChoice.getValue()+"."); // } else { // the original window is not opened // reset Choices list windowChoice.getChoices().clear(); windowChoice.getChoices().addAll(imageWindows); this.add(windowChoice); // } } else { addMessage("There are no images opened in ImageJ."); } if (windowChoice.isChoicesEmpty()) addMessage("Expected opened Image by the name "+windowChoice.getValue()+".", Color.RED); } } } /** * Displays a Popup-Window with the properties, that can be edited for this UnitElement. * @param point leave null to center on screen */ public void showProperties(Point point) { // PropertiesDialog not yet instantiated if (this.propertiesDialog == null) { this.propertiesDialog = new ImportUnitPropertiesDialog(this, point); this.propertiesDialog.addWindowListener(new WindowListener() { public void windowOpened(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowClosing(WindowEvent e) {} public void windowClosed(WindowEvent e) { e.getWindow().dispose(); } public void windowActivated(WindowEvent e) {} }); } // PropertiesDialog already exists, but is invisible else if (!propertiesDialog.isVisible()) { this.propertiesDialog.show(); } // PropertiesDialog already displayed, but has no focus else { this.propertiesDialog.toFront(); } } private ChoiceParameter getWindowChoiceParameter( final ArrayList<Parameter> parameterList) { return (ChoiceParameter) parameterList.get(WINDOW_PARAMETER_INDEX); } private void setImagePlus(ImagePlus image) { this.image = image; updateImageType(); } private Vector<String> getImageWindows() { Vector<String> imagelist = new Vector<String>(); int imageID; for (int i = 1; i < WindowManager.getImageCount()+1; i++) { imageID = WindowManager.getNthImageID(i); ImagePlus ip = WindowManager.getImage(imageID); if (ip != null) { imagelist.add(ip.getTitle()); } } return imagelist; } /** * The current ImageType is determined by the currently selected {@link ImagePlus} window. * The unit-icon and labels will be updated as well. * If no file is selected or the file doesn't exist, a message is displayed. */ public void updateImageType() { int imageType = -1; if(getImagePlus() != null) { imageType = getImageType(); int width = 48, height = 48; BufferedImage thumbnail = scaleThumbnail(width, height); this.unitComponentIcon.setIcon(thumbnail); } // change bit depth for all outputs setOutputImageType(imageType); } /** * The ImageType on the output depends on the current image. * This function updates all {@link Output}s to the specified imageType. * @param imageType */ public void setOutputImageType(final int imageType) { for (final Output output : outputs) { if(output.getDataType() instanceof ImageDataType) ((ImageDataType)output.getDataType()).setImageBitDepth(imageType); } } /** * Bit depth of the file behind the specified FilePath * @return */ public int getBitDepth() { ImagePlus imp = getImagePlus(); int bitDepth = 0; if(imp != null) { //imp.close(); bitDepth = imp.getBitDepth(); } return bitDepth; } /** * {@link ImagePlus} from the selected {@link ImagePlus} window in ImageJ. * @return */ public ImagePlus getImagePlus() { return this.image; } public int getImageType() { return ImageJHelper.getImageType(getImagePlus(), false); } /* * painting */ /* * (non-Javadoc) * @see de.danielsenff.imageflow.models.unit.UnitElement#paint(java.awt.Graphics, java.awt.image.ImageObserver) */ @Override public Rectangle paint(final Graphics g, final ImageObserver io) { if(getImagePlus() == null && !selected) { g.setColor(new Color(255,0,0,80)); g.fillRoundRect(origin.x, origin.y, getDimension().width, getDimension().height, unitComponentIcon.arc, unitComponentIcon.arc); } final Rectangle paint = super.paint(g, io); return paint; } private BufferedImage scaleThumbnail(int width, int height) { BufferedImage thumbnail = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = (Graphics2D) thumbnail.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.drawImage(getImagePlus().getImage(), 0, 0, width, height, null); g2.dispose(); return thumbnail; } }